• 洛谷 P3017 [USACO11MAR]Brownie Slicing G(二分,前缀和)


    传送门


    解题思路

    最小值最大————很显然先二分最终答案,然后贪心进行切割:
    从头开始判断每一行能否切成b块大于二分的数的蛋糕,若不能就不断向下加行。
    而判断过程可以用二维前缀和优化。

    AC代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    const int maxn=505;
    int n,m,a,b,ma[maxn][maxn],d[maxn][maxn];
    long long l,r;
    bool work(int x,int y,int value){
    	int lie=0;
    	for(int j=1;j<=m;j++){
    		int k=j;
    		//(x,j)-->(y,k)
    		while(k<=m&&d[y][k]-d[x-1][k]-d[y][j-1]+d[x-1][j-1]<value) k++;
    		j=k;
    		lie++;
    		if(k>m&&lie<=b) return 0;
    	}
    	if(lie<b) return 0;
    	return 1;
    }
    bool check(int x){
    	int hang=0;
    	for(int i=1;i<=n;i++){
    		int k=i;
    		while(k<=n&&!work(i,k,x)) k++;
    		i=k;
    		hang++;
    		if(k>n&&hang<=a) return 0;
    	}
    	if(hang<a) return 0;
    	return 1;
    }
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>m>>a>>b;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			cin>>ma[i][j];
    			r+=ma[i][j];
    			d[i][j]=d[i][j-1]+d[i-1][j]-d[i-1][j-1]+ma[i][j];
    		}
    	}
    	r/=a*b;
    	while(l!=r){
    		long long mid=(l+r+1)/2;
    		if(check(mid)) l=mid;
    		else r=mid-1;
    	}
    	cout<<l;
    	return 0;
    }
    
  • 相关阅读:
    centos7安装 mysqlclient 报错的解决办法
    linux yum配置代理
    mysql 基础知识
    centos7 安装MySQL
    win安装mysql
    centos7 安装Mariadb
    python socket
    python 协程
    python 线程
    python 进程
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15035168.html
Copyright © 2020-2023  润新知