ZOJ 1039 Number Game (状态压缩,记忆化搜索)
来源:互联网 发布:kmeans聚类算法java 编辑:程序博客网 时间:2024/05/17 20:12
转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题目:2-20这19个数字的游戏。每取走一个数之后,这个数的倍数便不能再取,而且某两个不能取的数的和,也不能再取。
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=39
由于只有19个数,通过状态压缩保存状态,进行记忆化搜索。dp[1<<19]即可,dp[i]表示可行集合为i时的必胜必败情况
接下来重要的是状态转移。
对于原状态state,如果要把数字x从集合中去除的话。首先要分为两个步骤
1、将x以及x的倍数去掉,这便是把一个数的特定位置0的操作,位运算轻松解决,详见代码
2、去除不在集合中的元素与x的倍数的和。这步可以倒过来实现,找到还在集合中的元素,从中减掉若干个x,判断这个新的数是否在集合中,如果不在,说明这个数是非法的,去除。也可以通过位运算解决
在必胜与必败中,N态必然有一个后继是P态,利用这点搞定。
最后要输出可行解,便是枚举删除某个数,判断是否转变为P态即可
#include<iostream>#include<cstdio>#include<ctime>#include<cstring>#include<cmath>#include<algorithm>#include<cstdlib>#include<vector>#define C 240#define TIME 10#define inf 1<<25#define LL long longusing namespace std;int dp[1<<19];int get_state(int state,int x){ int ret=state; //把x以及x的倍数去除 //首先把要删除的那位置为1,然后取反,最后与状态相与 for(int i=x;i<=20;i+=x) ret&=~(1<<(i-2)); for(int i=2;i<=20;i++){ //如果某个数还在集合当中,则判断是否有某个不在集合中的数和X的倍数组成 if((1<<(i-2))&ret){ for(int j=x;i-j-2>=0;j+=x) //如果数i为某个不在集合中的数以及x的和,则去除 if(!((1<<(i-j-2))&ret)){ ret&=~(1<<(i-2)); break; } } } return ret;}int get_dp(int state){ if(dp[state]!=-1) return dp[state]; for(int i=2;i<=20;i++){ if(state&(1<<(i-2))){ //将第i个数移出集合 int tmp=get_state(state,i); //P态得到N态 if(!get_dp(tmp)) return dp[state]=1; } } return dp[state]=0;}int main(){ memset(dp,-1,sizeof(dp)); dp[0]=0; int t,n,a[20],cas=0; scanf("%d",&t); while(t--){ scanf("%d",&n); int state=0; for(int i=0;i<n;i++){ scanf("%d",&a[i]); //初始状态 state|=1<<(a[i]-2); } printf("Scenario #%d:\n",++cas); if(get_dp(state)==0) puts("There is no winning move.\n"); else{ printf("The winning moves are:"); for(int i=0;i<n;i++){ //枚举去除,是否为必败态 int tmp=get_state(state,a[i]); if(!get_dp(tmp)) printf(" %d",a[i]); } puts(".\n"); } } return 0;}
- ZOJ 1039 Number Game (状态压缩,记忆化搜索)
- ZOJ 1039 Number Game 记忆化搜索+二进制状态压缩
- poj 1143 Number Game 博弈 记忆化状态压缩搜索
- ZOJ 1039 Number Game(SG博弈+状压+记忆化搜索)
- hdu4753Fishhead’s Little Game【状态压缩记忆化搜索+博弈】
- POJ 1351 Number of Locks (记忆化搜索 状态压缩)
- hdu 4753 Fishhead’s Little Game (记忆化搜索+状态压缩)
- ZOJ 3644 Kitty's Game(记忆化搜索+剪枝)
- poj 1143 Number Game (记忆化搜索)
- poj1143Number Game(记忆化搜索+二进制保存状态+DP)
- CF-63E - Sweets Game(记忆化搜索dp+状态压缩)
- hdu 4778 Gems Fight!(记忆化搜索+状态压缩)
- nyoj 832合并游戏(状态压缩+记忆化搜索)
- hdu4753 状态压缩dp博弈(记忆化搜索写法)
- hdu 4628 Pieces(状态压缩+记忆化搜索)
- UVa 10118 Free Candies (记忆化搜索+状态压缩)
- uva1508-Equipment 状态压缩 记忆化搜索
- loj 1011(状态压缩+记忆化搜索)
- 8点FFT的C语言实现
- HDOJ_ 1133 Buy the Ticket
- POJ1651
- Inline Virtual Functions
- 文件系统小结
- ZOJ 1039 Number Game (状态压缩,记忆化搜索)
- hdu2138 How many prime numbers(Miller_Rabbin随机素数测试)
- 关于JavaScript的两个建议
- 进制学习
- Android系统中设置TextView的行间距(非行高)
- OleDB简单用例
- sgmllib Introduction
- jQuery之checkbox全选
- POJ 2594 允许有相交点的最小路径覆盖