[SCOI2005]互不侵犯(状压Dp)
Posted cjgjh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SCOI2005]互不侵犯(状压Dp)相关的知识,希望对你有一定的参考价值。
题目
Solution
看到数据范围就可以想到状压,然后你就可以直接转移就好了?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<queue>
#include<algorithm>
#define ll long long
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
using namespace std;
inline int gi(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
inline ll gl(){
ll sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
int have(int s){
int ans=0;
while(s){
if(s&1)ans++;s>>=1;
}
return ans;
}
int n,siz[2010],gs[2010],cnt;
ll dp[12][2010][101];
void dfs(int i,int s,int sum){
if(i>=n){
siz[++cnt]=s;
gs[cnt]=sum;
return;
}
dfs(i+1,s,sum);
dfs(i+2,s+(1<<i),sum+1);
}
int main(){
int i,j,k,m;
n=gi();k=gi();
dfs(0,0,0);
//设dp[i][j][k]表示第i行的放置方案为j,总共放了k个的方案总数.
//dp[i][j][k]+=dp[i-1][m][k-have(j)];
for(i=1;i<=cnt;i++)
dp[1][i][gs[i]]=1;
for(i=2;i<=n;i++)
for(j=1;j<=cnt;j++)
for(int kk=1;kk<=cnt;kk++){
if(siz[j]&siz[kk])continue;
if((siz[j]<<1)&siz[kk])continue;
if(siz[j]&(siz[kk]<<1))continue;
for(int jj=k;jj>=gs[j];jj--)
dp[i][j][jj]+=dp[i-1][kk][jj-gs[j]];
}
ll ans=0;
for(j=1;j<=cnt;j++)
ans+=dp[n][j][k];
printf("%lld
",ans);
return 0;
}
以上是关于[SCOI2005]互不侵犯(状压Dp)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
BZOJ 1087 [SCOI2005]互不侵犯King (状压DP)