状压dp小练习(LuoGu)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状压dp小练习(LuoGu)相关的知识,希望对你有一定的参考价值。

状压dp小练习(LuoGu)

P1433 吃奶酪

d p [ i ] [ j ] dp[i][j] dp[i][j]表示状态 j j j下到达位置 i i i的最小距离。

枚举转移点。

时间复杂度: O ( n 2 2 n ) O(n^22^n) O(n22n)

int n;scanf("%d",&n);for(int i=0;i<n;i++){
		scanf("%lf%lf",&a[i].x,&a[i].y);
	}
	node o ={0,0};
	mst(dp,127);
	for(int i=0;i<n;i++) dp[i][1<<i]=dis(o,a[i]);
	int mx=1<<n;
	for(int i=1;i<mx;i++)
		for(int j=0;j<n;j++){
			if(i>>j&1){
				for(int k=0;k<n;k++){
					if(k==j) continue;
					if(i>>k&1){
						dp[j][i]=min(dp[j][i],dp[k][i^(1<<j)]+dis(a[j],a[k]));
					}
				}
			}
		}
	double ans=1e18;
	for(int i=0;i<n;i++)
		ans=min(ans,dp[i][mx-1]);
	printf("%.2f\\n",ans);

double 数组初始化无穷大的方式memset(dp,127,sizeof dp)


P5911 [POI2004]PRZ

枚举子集状压dp。

先预处理所有状态的 t , w t,w t,w

然后枚举子集转移。

时间复杂度: O ( 3 n ) O(3^n) O(3n)

code

int st=1<<n;
	for(int i=1;i<st;i++)
		for(int j=0;j<n;j++)
			if(i>>j&1) b[i]=max(b[i],a[j].t),c[i]+=a[j].w;
	mst(dp,0x3f);
	dp[0]=0;
	for(int i=0;i<st;i++)
		for(int j=i;j;j=(j-1)&i){
			if(c[j]<=W){
				dp[i]=min(dp[i],dp[i^j]+b[j]);
			}
		}
	printf("%d\\n",dp[st-1]);

P1879 [USACO06NOV]Corn Fields G

枚举前一行的状态进行转移。

时间复杂度: O ( n 2 2 n ) O(n2^{2n}) O(n22n)

code

for(int i=1;i<=n;i++)
		for(int j=0;j<m;j++){
			int x;scanf("%d",&x);
			if(x) a[i]|=1<<j;
		}
	dp[0][0]=1;
	int st=1<<m;
	for(int i=1;i<=n;i++)
		for(int j=0;j<st;j++)
			if((a[i]&j)==j){
				if(((j&(j>>1))==0)&&((j&(j<<1))==0)){
					for(int k=0;k<st;k++){
						if((j&k)==0) dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
					}
				}
			}
	int ans=0;
	for(int i=0;i<st;i++)
		ans=(ans+dp[n][i])%mod;
	printf("%d\\n",ans);

以上是关于状压dp小练习(LuoGu)的主要内容,如果未能解决你的问题,请参考以下文章

Luogu3694 邦邦的大合唱站队 (状压DP)

[luogu3959 noip2017] 宝藏 (状压dp)

P4163 [SCOI2007]排列(状压dp)

luogu 2157 状压dp

Luogu4221 WC2018州区划分(状压dp+FWT)

luogu P1441状压DP砝码称重