1 条题解

  • -2
    @ 2025-3-6 9:58:14

    宝藏图 题解

    题意简述

    n x m 的方格图,先水平剪成A条,然后对于每一横条,竖直剪成B块,求一块宝藏价值最小值的最大值。

    分析

    二分答案(当前的x是否能 在满足题意的剪法下 作为最小价值的块)。

    Warning

    不一定要剪成网格状的。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=507;
    int n,m,A,B,ans,a[N][N],add[N][N];
    int check(int x){
    	int row=0,lst_row=0;//row:剪了几横行; lst_row:上次横剪的位置 
    	for(int i = 1;i<=n;i++){
    		int col=0,lst_col=0;//col:剪了几竖行; lst_col:上次竖剪的位置
    		for(int j = 1;j<=m;j++){
    			//other: i~lst_row j~lst_col 的块内的价值总和
    			int other=add[i][j]-add[lst_row][j]-add[i][lst_col]+add[lst_row][lst_col];
    			//要保证x是价值最小的块 
    			if(other>=x)col++,lst_col=j;
    		}
    		if(col>=B)row++,lst_row=i;
    	}
    	return row>=A;
    }
    signed main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0);cout.tie(0);
    	cin>>n>>m>>A>>B;
    	for(int i = 1;i<=n;i++)
    		for(int j = 1;j<=m;j++)
    			cin>>a[i][j];
    	for(int i = 1;i<=n;i++)
    		for(int j = 1;j<=m;j++)
    			add[i][j]=add[i-1][j]+add[i][j-1]-add[i-1][j-1]+a[i][j];
    	int l=1,r=add[n][m];
    	while(l+1<r){
    		int mid=(l+r)>>1;
    		if(check(mid))l=mid;
    		else r=mid;
    	}
    	cout<<l<<'\n';
    	return 0;
    }
    
    • 1

    信息

    ID
    59
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    (无)
    递交数
    32
    已通过
    13
    上传者