分蛋糕
阿新 • • 發佈:2017-08-21
時間 思想 min 最小 cstring cor ostream mes con
- 總時間限制:
- 1000ms
- 內存限制:
- 65536kB
- 描述
-
有一塊矩形大蛋糕,長和寬分別是整數w 、h。現要將其切成m塊小蛋糕,每個小蛋糕都必須是矩形、且長和寬均為整數。切蛋糕時,每次切一塊蛋糕,將其分成兩個矩形蛋糕。請計算:最後得到的m塊小蛋糕中,最大的那塊蛋糕的面積下限。
假設w= 4, h= 4, m= 4,則下面的切法可使得其中最大蛋糕塊的面積最小。
假設w= 4, h= 4, m= 3,則下面的切法會使得其中最大蛋糕塊的面積最小:
- 輸入
- 共有多行,每行表示一個測試案例。每行是三個用空格分開的整數w, h, m ,其中1 ≤ w, h, m ≤ 20 , m ≤ wh. 當 w = h = m = 0 時不需要處理,表示輸入結束。
- 輸出
- 每個測試案例的結果占一行,輸出一個整數,表示最大蛋糕塊的面積下限。
- 樣例輸入
-
4 4 4 4 4 3 0 0 0
- 樣例輸出
-
4 6
- 來源:openjudge
- 參考代碼
/** 一看就是按遞歸的思想轉換成動規 dp[w][h][m],w:長h:寬m:塊數 表示長w寬h的蛋糕切m刀所能得到最大塊蛋糕面積的最小值 邊界條件: ①w*h<m,dp[w][h][m]=INF(最多w*h塊,每塊都分成1的大小,所以不會超過m塊) ②m=1,dp[w][h][1]=w*h 每一刀,看是橫切,還是豎切 取切後的最大塊中最小的 假設初始蛋糕左右是長上下是寬 得到的小塊蛋糕繼續切,直到切完m-1刀 */ ///代碼摘自:http://www.cnblogs.com/candy99/p/5792478.html #include <iostream> #include <cstring> using namespace std; const int N=22,INF=1e9; int f[N][N][N],w,h,m; void solve(){ memset(f,0,sizeof(f)); //邊界條件 for(int i=1;i<=w;i++) for(int j=1;j<=h;j++) f[i][j][1]=i*j; for(inti=1;i<=w;i++) for(int j=1;j<=h;j++) for(int k=2;k<=min(i*j,m);k++){ f[i][j][k]=INF; //橫切 for(int t=1;t<i;t++){ for(int p=1;p<k;p++) f[i][j][k]=min(f[i][j][k],max(f[t][j][p],f[i-t][j][k-p])); } //豎切 for(int t=1;t<j;t++){ for(int p=1;p<k;p++) f[i][j][k]=min(f[i][j][k],max(f[i][t][p],f[i][j-t][k-p])); } } } int main(int argc, const char * argv[]) { while(cin>>w>>h>>m){ if(w==0&&h==0&&m==0) break; solve(); cout<<f[w][h][m]<<"\n"; } return 0; }
該題一看就能知道用DP,可是實現起來有點復雜,我也沒有徹底搞明白,歡迎推薦更詳細,更易懂的題解,感激不盡!
分蛋糕