zoukankan      html  css  js  c++  java
  • LA4794 Sharing Chocolate

     

    题意:给出一个长宽确定的矩形,每次可以沿一条直线把它分割成两块长宽都为整数的矩形,问能否通过多次操作得到n块面积分别为a1,a2...an的矩形。

    与分蛋糕的生日快乐有点像。记忆化搜索、枚举子集。

    由于n很小可以直接状压,s表示需要得到的巧克力的状态集合。

    因为每次所有的要得到的巧克力面积和等于r*c,可以根据这个剪枝,同时把状态f[r][c][s]变成二维f[r][s]。

    然后发现如果写return 1,2;最后会返回2。

    //Serene
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn=17,maxs=(1<<15)+10;
    int n,r,c,tot[maxs];
    int f[110][maxs];
    
    int aa;char cc;
    int read() {
    	aa=0;cc=getchar();
    	while(cc<'0'||cc>'9') cc=getchar();
    	while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    	return aa;
    }
    
    bool ok(int r,int s) {
    	if(f[r][s]) return f[r][s]-1;
    	if(s==(s&(-s))) return f[r][s]=2,1;
    	int x,y,c=tot[s]/r;
    	for(x=(s-1)&s;x;x=(x-1)&s) {
    		y=s-x;
    		if(tot[x]%c==0&&ok(r*tot[x]/tot[s],x)&&ok(r*tot[y]/tot[s],y)) return f[r][s]=2,1;
    		if(tot[x]%r==0&&ok(r,x)&&ok(r,y)) return f[r][s]=2,1;
    	}
    	return f[r][s]=1,0;
    }
    
    int main() {
    	n=read();int tt=0;
    	while(n) {
    		r=read();c=read(); int x;
    		memset(tot,0,sizeof(tot));
    		memset(f,0,sizeof(f));
    		for(int i=1;i<=n;++i) tot[1<<(i-1)]=read();
    		for(int i=1;i<(1<<n);++i) {
    			x=(i&(-i)); if(i==x) continue;
    			tot[i]=tot[x]+tot[i^x];
    		}
    		printf("Case %d: ",++tt);
    		if(r*c!=tot[(1<<n)-1]||!ok(r,(1<<n)-1)) printf("No
    ");
    		else printf("Yes
    ");
    		n=read();
    	}
    	return 0;
    }
    

      

    弱者就是会被欺负呀
  • 相关阅读:
    【JAVA反射】自定义类加载器
    工厂模式+反射+泛型
    wsdl文件生成webservice代理类及使用生成的代理类
    WebApi 做接口遇到的问题总结
    region URL请求数据
    LinQ 创建连接、简单增删改查
    JS整理
    WebForm 全局对象、commend
    WebForm 内置对象、数据增删改、状态保持
    WebForm 控件(二)
  • 原文地址:https://www.cnblogs.com/Serene-shixinyi/p/7604093.html
Copyright © 2011-2022 走看看