P4850 [IOI2009]葡萄干raisins 记忆化搜索
$ \color{#0066ff}{ 題目描述 }$
普羅夫迪夫的著名巧克力大師Bonny需要切開一板帶有葡萄干的巧克力。巧克力是一個包含許多相同的方形小塊的矩形。小塊沿著巧克力的邊排列成n行m列,即共有nm塊。每個小塊上有1個或多個葡萄干,沒有葡萄干在小塊的邊上或者跨過兩個小塊。 最開始,巧克力是一整塊。Bonny需要把它切成上述的nm個獨立的小塊。因為Bonny很忙,她需要她的助手Sly peter幫她切。Peter只能從一端到另一端切直線并且他要為他的每一刀得到報酬。Bonny手頭沒有錢,但是她有足夠的葡萄干,所以她提出用葡萄干付給peter。Sly peter同意接受葡萄干,但是有下面的條件:每次他把給定的一塊巧克力切成兩小塊,他都要得到和那塊給定的巧克力上葡萄干數目相同的葡萄干。 Bonny想要付給peter盡可能少的葡萄干。她知道這nm個小塊中每一個小塊上葡萄干的數目。她可以選擇遞給peter的巧克力的順序,也可以告訴peter如何切(橫切還是豎切)以及從哪里切。請告訴Bonny如何把巧克力切成一個個獨立的小塊。使她能夠付給Sly peter盡可能少的葡萄干。
任務 寫一個程序,給定每個小塊上葡萄干的數目,計算Bonny要付給Sly peter的最少的葡萄干的數目。
\(\color{#0066ff}{輸入格式}\)
你的程序必須從標準輸入中讀取下列數據:
第一行包含整數n和m,以一個空格隔開。
接下來的n行描述了每個小塊上葡萄干的數目。這n行中第kth行描述的是第kth行小塊巧克力。每行包含m個整數,分別以一個空格隔開。這些整數描述的是該行從左到右的小塊。第kth行的第pth個整數表示位于第kth行第pth列的小塊上的葡萄干數目。
\(\color{#0066ff}{輸出格式}\)
你的程序必須向標準輸出寫入一行,該行包含一個整數;Bonny要付給Sly peter的最少的葡萄干的數目。
評分規則 有25分的評測數據,n,m<=7。
\(\color{#0066ff}{輸入樣例}\)
2 3 2 7 5 1 9 5\(\color{#0066ff}{輸出樣例}\)
77\(\color{#0066ff}{數據范圍與提示}\)
1<=n,m<=50 巧克力兩條邊上小塊的數目
1<=k,p<=1,000 第kth行第pth列的小塊上的葡萄干數目
\(\color{#0066ff}{題解}\)
一看這題,先搜索暴力有25pts,然后發現可以記憶化,然后。。。就A了。。這。。。
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define LL long long LL in() {char ch; LL x = 0, f = 1;while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));return x * f; } template<class T> bool chkmax(T &a, const T &b) { return a < b? a = b, 1 : 0; } template<class T> bool chkmin(T &a, const T &b) { return b < a? a = b, 1 : 0; } const int inf = 0x7fffffff; const int maxn = 1050; int n, m; int s[maxn][maxn], f[55][55][55][55]; int getsum(int x, int y, int xx, int yy) {return s[xx][yy] - s[x - 1][yy] - s[xx][y - 1] + s[x - 1][y - 1]; } int work(int x, int y, int xx, int yy) {if(f[x][y][xx][yy]) return f[x][y][xx][yy];if(x == xx && y == yy) return 0;int ans = inf;for(int i = x; i < xx; i++) chkmin(ans, work(x, y, i, yy) + work(i + 1, y, xx, yy));for(int i = y; i < yy; i++) chkmin(ans, work(x, y, xx, i) + work(x, i + 1, xx, yy));return f[x][y][xx][yy] = ans + getsum(x, y, xx, yy); } int main() {n = in(), m = in();for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + in();printf("%d\n", work(1, 1, n, m));return 0; }轉載于:https://www.cnblogs.com/olinr/p/10685427.html
總結
以上是生活随笔為你收集整理的P4850 [IOI2009]葡萄干raisins 记忆化搜索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络摄像头工作原理_好,更好,最好以预算
- 下一篇: Mbps和MBps