2196巧克力蛋糕 大视野评测

Description

    Bessie烘焙了一块巧克力蛋糕。这块蛋糕是由R*C(1 <= R,C <= 500)个小的巧克力蛋糕组成的。 第i行,第j列的蛋糕有N_ij(1 <= N_ij <= 4,000)块巧克力碎屑。 Bessie想把蛋糕分成A*B块,(1 <= A <= R,1 <= B <= C): 给A*B只奶牛。蛋糕先水平地切A-1刀 (只能切沿整数坐标切)来把蛋糕划分成A块。然后再把剩下来的每一块独立地切B-1刀, 也只能切沿整数坐标切。其他A*B-1只奶牛就每人选一块,留下一块给Bessie。由于贪心, 他们只会留给Bessie巧克力碎屑最少的那块。 求出Bessie最优情况下会获得多少巧克力碎屑。 例如,考虑一个5*4的蛋糕,上面的碎屑分布如下图所示: 1 2 2 1 3 1 1 1 2 0 1 3 1 1 1 1 1 1 1 1 Bessie必须把蛋糕切成4条,每条分成2块。Bessie能像这样切蛋糕: 1 2 | 2 1 --------- 3 | 1 1 1 --------- 2 0 1 | 3 --------- 1 1 | 1 1 1 1 | 1 1 因此,其他贪得无厌的牛拿完后,Bessie仍能够拿走3个巧克力碎屑。

Input

     第1行: 四个空格隔开的数: R, C, A ,B * 第2-R+1行: 第i+1行有C个整数, N_i1 , N_i2 .. N_iC

Output

     第1行: 一个整数: Bessie保证能拿到的最多碎屑数

Algorithm

    二分答案,然后用贪心思想来检查这个答案。注意题目中输入的a和b是分成几块而不是切几刀的意思。详解见代码。

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 int s[501][501]={0}; int r,c,a,b;
 6 bool judge(int k){
 7     int i=1,num=0,numa=0,numb=0,last=0;
 8     while (i<=r){
 9         num=0; numb=0;
10         for (int j=1;j<=c;j++){
11             num+=(s[i][j]-s[last][j]);
12             if (num>=k) {
13                 num=0; numb++; 
14             }
15         }
16         if (numb>=b) {
17             numa++; if (numa>=a) return true;
18             last=i; 
19         }
20         i++;
21     }
22     return false;
23 }
24 int main(){
25     scanf("%d%d%d%d",&r,&c,&a,&b);
26     for (int i=1;i<=r;i++)
27         for (int j=1;j<=c;j++){
28             scanf("%d",&s[i][j]);
29             s[i][j]+=s[i-1][j];
30         }
31     int left=0,right=0;
32     for (int i=1;i<=c;i++) right+=s[r][i];
33     //printf("%d",right);
34     int ans=0;
35     while (left<=right){
36         int mid=(left+right)/2;
37         if (judge(mid)) {
38             left=mid+1;
39             if (mid>ans) ans=mid;
40         } 
41         else right=mid-1;
42     }
43     printf("%d",ans);
44     return 0;
45 } 

 

 

Source

    http://www.lydsy.com/JudgeOnline/problem.php?id=2196

posted @ 2016-12-15 15:43  lztlztlzt  阅读(135)  评论(1编辑  收藏  举报