zoukankan      html  css  js  c++  java
  • Usaco*Brownie Slicing

    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保证能拿到的最多碎屑数

    Sample Input

    5 4 4 2
    1 2 2 1
    3 1 1 1
    2 0 1 3
    1 1 1 1
    1 1 1 1

    Sample Output

    3
     
     
    二分答案,贪心判断以现在的值为答案能否切成a*b块。
     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 int a[501][501]={0};
     5 int r,c,a1,b1;
     6 
     7 bool check(int now)//判断当前答案的正确性
     8 {
     9     int tot=0,x=0,y=0,j=0,i=0,lasti=0;
    10     while (i<r)//i为访问到第几行,避免越界
    11     {
    12         ++i;
    13         j=0;
    14         y=0;//当前(lasti~i这一块面包被竖着切成y块面包)
    15         while ((j<c)&&(y<b1))
    16         {
    17             tot=0;
    18             while ((tot<now)&&(j<c))//利用贪心,一列一列加
    19             {
    20                 ++j;
    21                 for (int i2=lasti+1;i2<=i;++i2)
    22                   tot=tot+a[i2][j];
    23             }
    24             if (tot>=now)//如果可以产生一块新的面包,则将y+1
    25               ++y;
    26         }
    27         if (y>=b1)//当lasti~i行的面包能被切成大于等于B(b1)块且每一块的碎屑都大于mid,x+1,开始枚举下一次该切在哪
    28         {
    29             ++x;
    30             lasti=i;
    31         }
    32     }34     if (x>=a1)
    35       return true;
    36     return false;
    37 }
    38 
    39 int main()
    40 {
    41     cin>>r>>c>>a1>>b1;
    42     int right=0;
    43     for (int i=1;i<=r;++i)
    44       for (int j=1;j<=c;++j)
    45       {
    46           cin>>a[i][j];
    47           right+=a[i][j];
    48       }
    49     int ans=0,left=0,mid=0;
    50     while (left<=right)//二分答案
    51     {
    52         mid=(left+right)/2;
    53         if (check(mid)==true)
    54         {
    55           left=mid+1;
    56           ans=mid;//避免出现死循环
    57         }
    58         else right=mid-1;
    59     }
    60     cout<<ans<<endl;
    61     return 0;
    62 }
  • 相关阅读:
    C#下载文件代码更新20070920
    判断IP地址是否合法的sql2000使用存储过程跟函数
    百万级SQL分页存储过程
    C#批量重命名文件代码的实现
    单个分页的存储过程
    阿江网站访问统计系统设计构思分析
    c#查询QQ状态是否在线查询代码
    C# public class Person
    C#禁止应用程序的多重运行
    Outlook最小化到托盘的设置方法
  • 原文地址:https://www.cnblogs.com/Maxxzy/p/6183191.html
Copyright © 2011-2022 走看看