Baidu Star 問題解決 (ケーキ部門)

シャオドゥはケーキカットの準備をしています。このケーキの大きさは N*N で、ケーキの各部分の重さは均一ではありません。

Xiaodu は、垂直または水平の合計 K 本のナイフを切ることができます。Xiaodu は、K 個のナイフを切った後の最も重いケーキの重さを知りたいと考えています。

フォーマット

入力形式:

行 1 には N と K が含まれます。そのうち: 2≤

入力形式:

行 1 には N と K が含まれます。それらの中: 2≤N≤15、1≤K≤2N−2;
行 2 ~ 1+N: 各行に N 個の数字があり、この行のケーキの各位置の重量 W を表します。そのうち: 0≤W≤1000。

≤15;

出力フォーマット:

整数を出力します。最も重いケーキが最も軽いものになります。

サンプル1 

入力:

3 2
1 1 2
1 1 2
2 2 5

出力:

5

#include<bits/stdc++.h> 

using namespace std;
int n,k,fal,max_;
int a[20][20],sum[20][20],col[20],cnt[20],temp[20];
int get_sum(int x1,int y1,int x2,int y2){
    return sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1];
}
bool check(int m){
    if(m<max_) return false;
    for(int i=0;i<(1<<(n-1));i++){
        fal=0;
        memset(col,0,sizeof(col));
        memset(cnt,0,sizeof(cnt));
        memset(temp,0,sizeof(temp));
        vector<int> v;
        int count=0,ans=0,tmp=i;
        while(tmp){
            count++;
            if(tmp&1){
                v.push_back(count);
                ans++;
            }
            tmp/=2;
        }
        if(ans>k) continue;
        v.push_back(n);
        int p=0,top=1,down;
        for(int j=1;j<=n;j++){
            p=0,top=1;
            for(int x:v){
                down=x;
                int now=get_sum(top,j,down,j);
                if(now>m){
                    fal=1;break;
                }
                cnt[++p]+=now;
                if(col[j-1]){
                    cnt[p]=now;
                }
                temp[p]=now;
                if(cnt[p]>m){
                    col[j-1]=1;
                    cnt[p]=now;
                    for(int ii=1;ii<p;ii++) cnt[ii]=temp[ii];
                }
                top=down+1;
            }if(fal) continue;
            for(int j=1;j<=n-1;j++){
                if(ans<=k) return true;
            }
            return false;
        }
    }
}
int main( )
{ 
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];
            max_=max(max_,a[i][j]);
            sum[i][j]=a[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
        }
    }
    int l=0,r=2000*15*15;
    while(l<=r){
        int m=(l+r)>>1;
        if(check(m)) r=m-1;
        else l=m+1;
    }cout<<l<<'\n';
    return 0;
}

 

おすすめ

転載: blog.csdn.net/qq_71356343/article/details/132892850