题目大意:
就是说两个人交换选一些数,如果a,b被选过了,那么k*a+m*b(k,m >=0 )这样的数就不能再被选择,现在给你一些还没有选的数,问选哪个数可以使你必胜
如样例:
2 5
如果你选2,由于3已经选过了,而2+3=5,所以5也不能备选择。所以选2就为必胜的选择
我的思路:
,这道题的最初要想到的就是,由于题目的给的数的范围很小,<=20。所以表示这些数的集合就可以用二进制模拟。
用一个DP数组就可以存下,他有两个值就是0和1,表示必胜和必输两个状态。详见代码:
1 #include2 #include 3 #include 4 #include 5 #define MAX(a,b) (a) > (b)? (a):(b) 6 #define MIN(a,b) (a) < (b)? (a):(b) 7 #define mem(a) memset(a,0,sizeof(a)) 8 #define INF 1000000007 9 #define MAXN 1<<2010 #define MACN 2011 12 #define JUDGE (((1<<(ma[j]-ma[i]-1)) & ~st) &&(ma[j]-ma[i] != 1)) || (!((ma[j]+1)%(ma[i]+1)))13 14 using namespace std;15 16 int DP[MAXN],ma[MACN],vis[MAXN];17 int N;18 19 int search(int k,int state)20 {21 if(vis[state])return DP[state];22 vis[state]=1;23 if(state == 0)return 0;24 if(k == 1)return DP[state] = 1;//集合里面只有一个数了,一定是必胜状态25 int i, j, key=0;26 for(i = 0;i < N;i ++ )27 {28 int st = state;29 if((1<