zoukankan      html  css  js  c++  java
  • BZOJ 1169: [Baltic2008]Grid

    一个矩阵,可以横着切S刀,竖着切R刀,求小矩阵和最大的最小是多少。
    二分答案,dfs出竖着切的,横着贪心check。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 25;
    ll a[maxn][maxn];
    int n,m,R,S;
    
    template<typename T> inline void read(T &x){
    x=0;T f=1;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f;
    }
    
    template<typename A,typename B> inline void read(A&x,B&y){read(x);read(y);}
    template<typename A,typename B,typename C> inline void read(A&x,B&y,C&z){read(x);read(y);read(z);}
    template<typename A,typename B,typename C,typename D> inline void read(A&x,B&y,C&z,D&w){read(x);read(y);read(z);read(w);}
    
    bool ok;
    
    int dl[maxn];
    ll mid;
    ll bs[maxn];
    
    bool isok(){
    	//if(dl[0]==2&&dl[1]==4) cout<<"mid"<<mid<<endl;
    	dl[R]=n;
    	memset(bs,0,sizeof bs);
    	//int bef=0;
    	int cnt=0;
    	for(int i=1;i<=m;i++){
    		bool can=1;
    		for(int j=0;j<=R;j++){
    			if(j==0&&bs[j]+a[dl[j]][i]-a[dl[j]][i-1]>mid) can=0;
    			else if(bs[j]+a[dl[j]][i]-a[dl[j]][i-1]-(a[dl[j-1]][i]-a[dl[j-1]][i-1])>mid)
    				can=0;
    		}
    		if(!can){
    			cnt++;
    			for(int j=0;j<=R;j++){
    				bs[j]=0;
    			}
    		}
    		for(int j=0;j<=R;j++){
    			if(j==0) bs[j]+=a[dl[j]][i]-a[dl[j]][i-1];
    			else bs[j]+=a[dl[j]][i]-a[dl[j]][i-1]-(a[dl[j-1]][i]-a[dl[j-1]][i-1]);
    		}
    		for(int j=0;j<=R;j++)
    			if(bs[j]>mid) return 0;
    	}
    	return cnt<=S;
    }
    
    void dfs(int now,int dep){
    	if(ok) return;
    	if(dep==R){
    		if(isok()) ok=1;
    		return;
    	}
    	for(int i=now;i<n;i++){
    		dl[dep]=i;
    		dfs(i+1,dep+1);
    	}
    }
    
    bool check(ll mid){
    	ok=0;
    	dfs(1,0);
    	if(ok) return 1;
    	return 0;
    }
    
    int main(){
    	//freopen("in.txt","r",stdin);
    	read(n,m,R,S);
    	R=min(R,n-1);S=min(S,m-1);
    	ll l=0,r=0;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			read(a[i][j]),r+=a[i][j];
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
    	//for(int i=1;i<=n;i++)
    	//	for(int j=1;j<=m;j++)
    	//		printf("%d%c",(int)a[i][j]," 
    "[j==m]);
    	ll res=-1;
    	//cout<<check(mid=31)<<endl;
    	//l=r=130;
    	while(l<=r){
    		mid=(l+r)/2;
    		if(check(mid))
    			r=(res=mid)-1;
    		else l=mid+1;
    	}
    	cout<<res;
    	return 0;
    }
    
  • 相关阅读:
    年轻人的第一个 Spring Boot 应用,太爽了!
    面试问我 Java 逃逸分析,瞬间被秒杀了。。
    Spring Boot 配置文件 bootstrap vs application 到底有什么区别?
    坑爹的 Java 可变参数,把我整得够惨。。
    6月来了,Java还是第一!
    Eclipse 最常用的 10 组快捷键,个个牛逼!
    Spring Cloud Eureka 自我保护机制实战分析
    今天是 Java 诞生日,Java 24 岁了!
    厉害了,Dubbo 正式毕业!
    Spring Boot 2.1.5 正式发布,1.5.x 即将结束使命!
  • 原文地址:https://www.cnblogs.com/foreignbill/p/7921148.html
Copyright © 2011-2022 走看看