zoukankan      html  css  js  c++  java
  • Jzoj4743 积木

    由于n很小(<=15)我们考虑状态压缩

    显然可以用三进制(雾)但是太浪费了

    我们令f[i][j][s]表示现在已用的积木状态为S,最上面那个积木是第i个,其中这个积木的第j(0<=j<3)条边是竖着的(不在上表面)

    转移的时候枚举i'和j‘判断一下即可

    由于每个积木边长顺序没有影响所以可以先排序方便比较

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int f[16][3][1<<16]={0},a[20][3]={{1<<30,1<<30,1<<30}},n,MS,A=0;
    inline void max(int& x,int y){ x<y?x=y:0; }
    inline bool ok(int i,int j,int x,int y){
    	int f[2],g[2],t1=0,t2=0;
    	for(int k=0;k<3;++k) if(k^j) f[t1++]=a[i][k];
    	for(int k=0;k<3;++k) if(k^y) g[t2++]=a[x][k];
    	return f[0]>=g[0] && f[1]>=g[1];
    }
    int main(){
    	scanf("%d",&n);  MS=1<<n+1;
    	for(int i=1;i<=n;++i){
    		scanf("%d%d%d",a[i],a[i]+1,a[i]+2);
    		sort(a[i],a[i]+3);
    	}
    	f[0][0][1]=1;
    	for(int S=0;S<MS;++S)
    		for(int i=0;i<=n;++i)
    			for(int j=0;j<3;++j)
    			if(f[i][j][S])
    				for(int di=1;di<=n;++di)
    				if(!(S&(1<<di)))
    					for(int dj=0;dj<3;++dj)
    						if(ok(i,j,di,dj)) max(f[di][dj][S|(1<<di)],f[i][j][S]+a[di][dj]);
    	for(int S=0;S<MS;++S)
    		for(int i=0;i<=n;++i)
    			for(int j=0;j<3;++j) max(A,f[i][j][S]);
    	printf("%d
    ",--A);
    }

  • 相关阅读:
    修改eclipse的背景色(转载)
    c#调用 windows api实现WinForm中嵌入EXE程序
    VS2008序列号
    Microsoft Visual Studio 2005 获取与升级
    Oracle数组一般可以分为固定数组和可变数组
    深圳香港之行杂记
    [难过]小明住院了
    青岛之行杂记
    喀纳斯之行杂记
    亲历北京721大雨
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477194.html
Copyright © 2011-2022 走看看