【bzoj1087】【互不侵犯King】状压dp裸题(浅尝ACM-D)
2017-07-06 19:29
302 查看
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=54329606
向大(hei)佬(e)势力学(di)习(tou)
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
3 2
Sample Output
16
看数据范围,1<=N<=9,什么东西的的数据范围这么小啊,总不可能是放水,所以想来也是状态压缩dp了
说道状压dp,刚开始学习的时候打的是salesman,是一道用记忆化搜索的题,害我进了一个误区,竟以为状压都要用记忆化搜索。然而状压的实质只是将状态用二进制的数字表示,结合进各种dp中去。
这类题的状态通常有优化,枚举的2^N的数字中有很大一部分是不合法的,如果每次都枚举完再判断的话有可能会超时,所以可以用一个state数组来储存合法状态(但要注意state[i]中的i不是二进制状态)
另外灵活应用位运算来判断合法不合法也是一个重要的技巧
目前我所总结到的:
1、& 可以判断是否在同一列
2、<< 和>> 可以挪动,与其他运算符结合使用可以判断斜方向上的东西
3、| 并上两行的,通常用于三行的dp
代码(有我的笨判断方法,好在对时间复杂的要求不高)
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=15; struct Node{ int state,cnt; }a[600]; int sz=0; int n,K; ll dp [600][N*N]; bool check(int state){ bool bj=0; int now; while(state){ now=(state&1); if(bj==0&&now==1) bj=1; else if(bj==1){ if(now==1) return false; bj=0; } state>>=1; } return true; /*if(state&(state<<1)) return false; if(state&(state>>1)) return false; return true;*/ } int lowbit(int x){ return x&(-x); } int count(int state){ int now,rt=0; while(state){ rt++; state-=lowbit(state); } return rt; } bool check2(int a,int b){ if((a&b)!=0) return false; if(check((a|b))==false) return false; /*if((a&(b<<1))!=0) return false; if((a&(b>>1))!=0) return false;*/ return true; } int main(){ scanf("%d%d",&n,&K); for(int i=0;i<(1<<n);i++){ if(check(i)){ a[sz].state=i; a[sz].cnt=count(i); sz++; } } for(int i=0;i<sz;i++){ dp[1][i][a[i].cnt]=1; } for(int i=2;i<=n;i++){ for(int j=0;j<sz;j++){ for(int k=0;k<=K;k++){//0个也是可能的 for(int g=0;g<sz;g++){ if(check2(a[j].state,a[g].state)&&k-a[j].cnt>=0) dp[i][j][k]+=dp[i-1][g][k-a[j].cnt]; } } } } ll ans=0; for(int i=0;i<sz;i++){ ans+=dp [i][K]; } printf("%lld",ans);//long long return 0; }
总结:
最近总死在long long 上,下手前要先思考一下可能会达到的数据范围
相关文章推荐
- 【bzoj1087】【互不侵犯King】状压dp裸题(浅尝ACM-D)
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
- 【BZOJ1087】【SCOI2005】【互不侵犯king】【状压dp】
- bzoj 1087: [SCOI2005]互不侵犯King【状压dp】
- BZOJ1087: [SCOI2005]互不侵犯King 状压DP
- [SCOI2005] BZOJ 1087 互不侵犯King - 状压dp
- BZOJ1087 [SCOI2005]互不侵犯King 状压dp
- 【状压dp】【bzoj 1087】【SCOI 2005】互不侵犯King
- BZOJ 1087 SCOI 2005 互不侵犯King 状压DP
- 状压入门--bzoj1087: [SCOI2005]互不侵犯King【状压dp】
- 【BZOJ 1087】【SCOI 2005】互不侵犯King 【状压DP】
- BZOJ 1087 SCOI2005 互不侵犯King 状压DP
- 【轮廓线DP,状压DP】BZOJ1087 [SCOI2005]互不侵犯King
- bzoj 1087: [SCOI2005]互不侵犯King
- 【BZOJ 1087】[SCOI2005]互不侵犯King
- BZOJ 1087 互不侵犯king
- [SCOI2005][BZOJ1087] 互不侵犯King
- BZOJ1087 [SCOI2005]互不侵犯King 状态压缩DP
- BZOJ1087 洛谷P1896 [SCOI2005]互不侵犯King
- [bzoj1087]: [SCOI2005]互不侵犯King(状压dp)