【BZOJ 1087】【SCOI 2005】 互不侵犯King
2015-02-14 18:56
393 查看
状态压缩DP,f[i][j][k]保存第i行(包括第i行)之前放了j个国王,当前行用二进制表示后对应十进制数为k的方案数。
count[k]表示k所对应的二进制中1的个数。
状态转移方程比较显然:f[i][j][k]=sum{f[i-1][j-count[k]][p]};
其中k满足 (k&(k<<1))==0
其中p满足 (p&(p<<1))==0&&((p<<1)&k)==0&&(p&k)==0&&((p>>1)&k)==0
code:
count[k]表示k所对应的二进制中1的个数。
状态转移方程比较显然:f[i][j][k]=sum{f[i-1][j-count[k]][p]};
其中k满足 (k&(k<<1))==0
其中p满足 (p&(p<<1))==0&&((p<<1)&k)==0&&(p&k)==0&&((p>>1)&k)==0
code:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; long long f[10][100][600],n,K; int count[600]; int main() { int i,j,x,p,k; long long sum=0; scanf("%d%d",&n,&K); memset(f,0,sizeof(f)); x=pow(2,n)-1; for (i=0;i<=x;++i) { j=i; while(j>0) { j&=(j-1); count[i]++; } } for (i=0;i<=x;++i) if ((i&(i<<1))==0) f[1][count[i]][i]=1; for (i=2;i<=n;++i) for (j=0;j<=K;++j) for (k=0;k<=x;++k) if (((k&(k<<1))==0)&&(j>=count[k])) for (p=0;p<=x;++p) if (((p&(p<<1))==0)&&((p&k)==0)&&((k&(p>>1))==0)&&((k&(p<<1))==0)) f[i][j][k]+=f[i-1][j-count[k]][p]; for (i=0;i<=x;++i) sum+=f [K][i]; printf("%lld\n",sum); }
相关文章推荐
- BZOJ1087: [SCOI2005]互不侵犯King
- 【bzoj1087】[SCOI2005]互不侵犯King
- 【BZOJ 1087】【SCOI 2005】互不侵犯King
- [BZOJ1087] [SCOI2005]互不侵犯King
- 【BZOJ】1087【SCOI2005】互不侵犯King
- BZOJ 1087: [SCOI2005]互不侵犯King
- BZOJ 1087 [SCOI2005]互不侵犯King
- [BZOJ1087][SCOI2005]互不侵犯King(状压)[第二题]
- bzoj1087【SCOI2005】互不侵犯King
- 【bzoj 1087】[SCOI2005]互不侵犯King 状压dp
- 【BZOJ】1087: [SCOI2005]互不侵犯King
- BZOJ 1087: [SCOI2005]互不侵犯King( 状压dp )
- 【状态压缩DP】【BZOJ1087】【SCOI2005】互不侵犯king
- bzoj[1087][SCOI2005]互不侵犯King
- [BZOJ1087][SCOI2005]互不侵犯King(状压dp)
- 【BZOJ1087】【SCOI2005】【互不侵犯king】【状压dp】
- BZOJ 1087: [SCOI2005]互不侵犯King
- BZOJ1087 [SCOI2005]互不侵犯King 状压dp
- Bzoj 1087: [SCOI2005]互不侵犯King(状压DP)
- 状压入门--bzoj1087: [SCOI2005]互不侵犯King【状压dp】