题目大意:

就是说两个人交换选一些数,如果a,b被选过了,那么k*a+m*b(k,m >=0 )这样的数就不能再被选择,现在给你一些还没有选的数,问选哪个数可以使你必胜

如样例:

2 5

如果你选2,由于3已经选过了,而2+3=5,所以5也不能备选择。所以选2就为必胜的选择

我的思路:

,这道题的最初要想到的就是,由于题目的给的数的范围很小,<=20。所以表示这些数的集合就可以用二进制模拟。

用一个DP数组就可以存下,他有两个值就是0和1,表示必胜和必输两个状态。详见代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 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<<20
10 #define MACN 20
11
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<<ma[i]) & state)
30         {
31             for(j = i+1; j < N; j ++ )//首先去掉ma[i]的倍数和(ma[j]-ma[i])已经使用了的ma[j]
32             {
33                 if( ((1<<ma[j]) & st) && (JUDGE) )
34                 {
35                     st ^= (1<<ma[j]);
36                 }
37             }
38             key = search(k-1, st^(1<<ma[i]));
39             if( !key )return DP[state]=1;//一旦下一个状态有必输的状态,那这个状态就是必胜的
40         }
41     }
42     return DP[state]=0;
43 }
44
45 int main()
46 {
47     int cas=1;
48     while(~scanf("%d",&N) && N)
49     {
50         mem(vis);
51         int i,j,state=0;
52         int ans[MACN]={0},count=0;
53
54         for(i=0;i<N;i++)
55         {
56             scanf("%d",&ma[i]);
57             ma[i]--;
58             state ^= (1<<ma[i]);//初始化状态集合state
59         }
60
61         sort(ma,ma+N);
62         for(i = 0; i < N; i ++ )
63         {
64             int st = state;
65             for(j = i+1; j < N; j ++ )
66             {
67                 if(JUDGE) st ^= (1<<ma[j]);
68             }
69             if(search(N-1, (1<<ma[i])^st) == 0)
70             {
71                 ans[count++] = ma[i]+1;
72             }
73         }
74
75         printf("Test Case #%d\n", cas++);
76         if(!count)printf("There's no winning move.\n\n");
77         else {
78             printf("The winning moves are:");
79             for(i=0;i<count;i++)
80                 printf(" %d", ans[i]);
81             printf("\n\n");
82         }
83     }
84     return 0;
85 }

转载于:https://www.cnblogs.com/gj-Acit/archive/2013/06/05/3118977.html

POJ1143 Number Game(DP)相关推荐

  1. HDU 3709 Balanced Number (数位DP)

    题意 求出[x, y] 范围内的平衡数,平衡数定义为:以数中某个位为轴心,两边的数的偏移量为矩,数位权重,使得整个数平衡. 思路 外层枚举平衡点,然后数位DP即可.设计状态: dp[pos][o][l ...

  2. fzu 2109 Mountain Number 数位DP

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2109 题意: 如果一个>0的整数x,满足a[2*i+1] >= a[2*i]和a[2*i+2],则 ...

  3. HDU - 3709 Balanced Number(数位dp)

    题目链接:点击查看 题目大意:将一串数字视为天平,两端平衡的数字称为平衡数,并求出一段闭区间中平衡数的个数.所谓的平衡条件即为力臂与 力相乘后两端的数量和可以抵消,例如数字4139可以视为以3为中轴的 ...

  4. HDU odd-even number 数位dp

    题意 在l到r区间内求有多少个符合条件"当前数中所有连续的奇数长度是偶数 所有连续的偶数长度是奇数"的个数 分析 典型的数位dp问题 我们设置dp数组时可以根据 dp[pos][p ...

  5. HDU 5787 wolf Number 数位dp

    题意 题目就是说让我们在l到r的数字中求得有多少个连续k为不相同的数 1≤L≤R≤1e18 2≤K≤5 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

  6. C语言Catalan number卡特兰数(使用n个键可以搜索多少个二叉搜索树)的算法(附完整源码)

    C语言使用n个键可以搜索多少个二叉搜索树的算法 C语言使用n个键可以搜索多少个二叉搜索树的算法完整源码(定义,实现,main函数测试) C语言使用n个键可以搜索多少个二叉搜索树的算法完整源码(定义,实 ...

  7. acm寒假特辑1月24日 HDU - 2191(背包)/CodeForces - 500A

    A - 1 CodeForces - 500A (签到) New Year is coming in Line World! In this world, there are n cells numb ...

  8. LeetCode题组:第322题-零钱兑换

    1.题目 难度:中 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 示例 1: 输 ...

  9. LeetCode面试必刷题目总结 持续更新中...

    说明 文章源地址:sanzo.top/#/post/算法与数据结构/算法题 多数元素 题目链接 找到数组中众数(出现次数>⌊n2⌋>\lfloor\frac{n}{2}\rfloor> ...

最新文章

  1. 6、单机运行环境搭建之 --CentOS-6.4安装MySQL 5.6.10并修改MySQL的root用户密码
  2. 转: Div与table的区别
  3. java压缩zip文件中文乱码问题
  4. intern cookie 纠结之二
  5. spring mvc 基于表单的认证过程及cookie应用和session管理
  6. ubuntu 下 maven安装
  7. python初学者怎么入门-python初学者怎么入门
  8. LOJ #6268. 分拆数
  9. Android图片剪裁库:uCrop
  10. Python学习笔记——python基础之Python实现名片管理系统
  11. Variation calling and annotation
  12. 人生经典定律[收藏]
  13. html5 canvas消除锯齿,HTML5 Canvas 如何取消反锯齿绘图
  14. AspenTech利用ExaGrid实现全球数据备份和恢复策略的现代化
  15. matlab怎么绘制零极点,matlab中画系统零极点的方法
  16. Fuchsia OS简介
  17. jboss portal+MySql5 安装使用手册
  18. 使用HttpClient下载图片常用代码,以及下载失败原因
  19. Macbook M1开启允许任意来源应用
  20. Win7安装完成后对系统的优化设置

热门文章

  1. 如何给textbox中的文本设置垂直对齐,以及右对齐
  2. coc跑团san数值规则_为什么B站上有些coc跑团7版规则san值四五十,但是掉的时候只是掉1D3,是不是应该是20上限?...
  3. 自动化测试工具有哪些_软件测试工程师要具备哪些能力和技能?
  4. 解决Kali Linux XFCE桌面Tab无法补全
  5. Xamarin图表开发基础教程(5)OxyPlot框架
  6. Kali Linux又增加一个顶级域名kali.download
  7. ProxyStrike运行bug解决办法
  8. 交流潮流matlab程序,大神们,求个电力系统潮流计算的matlab程序。
  9. c++fabs函数_二次函数背景下的菱形存在性问题
  10. java邮件附件默认路径_JavaMail - 文件夹管理( Folder Management)