• 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);
    }

  • 相关阅读:
    Vue 获取URL链接后面的参数值
    Vue 跳转到指定页面,返回到上一页
    Vant 插件
    Vue 返回上一页,记住上一页的数据
    vue pc端支付宝支付
    Spring 中的事务
    数据库中锁与事务
    《产品方法论》 读书笔记
    设计模式之装饰者模式
    设计模式之单例模式
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7887155.html
Copyright © 2020-2023  润新知