状压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)的主要内容,如果未能解决你的问题,请参考以下文章
[luogu3959 noip2017] 宝藏 (状压dp)