1. 程式人生 > >Brownie Slicing(二分枚舉答案)

Brownie Slicing(二分枚舉答案)

last 判斷 rom scan square ike 更新 pre cin

描述

Bessie has baked a rectangular brownie that can be thought of as an RxC grid (1 <= R <= 500; 1 <= C <= 500) of little brownie squares.
The square at row i, column j contains N_ij (0 <= N_ij <= 4,000) chocolate chips.
Bessie wants to partition the brownie up into A*B chunks (1 <= A <= R; 1 <= B <= C): one for each of the A*B cows. The brownie is cut by first making A-1 horizontal cuts (always along integer
coordinates) to divide the brownie into A strips. Then cut each strip *independently* with B-1 vertical cuts, also on integer boundaries. The other A*B-1 cows then each choose a brownie piece, leaving the last chunk for Bessie. Being greedy, they leave Bessie the brownie that has the least number of chocolate chips on it.
Determine the maximum number of chocolate chips Bessie can receive, assuming she cuts the brownies optimally.
As an example, consider a 5 row x 4 column brownie with chips distributed like this:
1 2 2 1
3 1 1 1
2 0 1 3
1 1 1 1
1 1 1 1
Bessie must partition the brownie into 4 horizontal strips, each with two pieces. Bessie can cut the brownie like this:

1 2 | 2 1
---------
3 | 1 1 1
---------
2 0 1 | 3
---------
1 1 | 1 1
1 1 | 1 1

Thus, when the other greedy cows take their brownie piece, Bessie still gets 3 chocolate chips.

輸入

* Line 1: Four space-separated integers: R, C, A, and B

* Lines 2..R+1: Line i+1 contains C space-separated integers: N_i1, ..., N_iC

輸出

* Line 1: A single integer: the maximum number of chocolate chips that Bessie guarantee on her brownie

樣例輸入

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

樣例輸出

3

題目大意:

給一個R*C的矩陣,先橫著切A-1刀,分成A份,然後每份切B-1刀,最終有A*B份,求裏面的最小值的最大值。

二分枚舉答案,然後判斷是否可行。

#include <bits/stdc++.h>
using namespace std;
int r,c,a,b;
int s[505][505],pre[505][505];
bool check(int x)
{
    int cnt=0,la=0;
    for(int i=1;i<=r;i++)
    {
        int sum=0,num=0;
        for(int j=1;j<=c;j++)
        {
            
if(sum+pre[i][j]-pre[i][j-1]-pre[la][j]+pre[la][j-1]<x) sum+=pre[i][j]-pre[i][j-1]-pre[la][j]+pre[la][j-1]; else sum=0,num++; } if(num>=b)///說明這部分能被切除b份,且符合要求 la=i,cnt++;///更新上一次切的行的位置 } return cnt>=a; } int main() { scanf("%d%d%d%d",&r,&c,&a,&b); for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) scanf("%d",&s[i][j]); for(int i=1;i<=r;i++)///處理前綴和 for(int j=1;j<=c;j++) pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+s[i][j]; int L=0,R=pre[r][c],ans; while(L<=R) { //cout<<L<<‘ ‘<<R<<‘\n‘; int mid=(L+R)>>1; if(check(mid)) L=mid+1,ans=mid; else R=mid-1; } printf("%d\n",ans); return 0; }

Brownie Slicing(二分枚舉答案)