asdfaskdjgasljgd

lajsdgljasldfjlsj

lajsdlgjasldf

asdljgalsjdg

Time Limit: 1000MS Memory Limit: 65536K

Total Submissions: 3432 Accepted: 1399
Description

Christine and Matt are playing an exciting game they just invented: the Number Game. The rules of this game are as follows.
The players take turns choosing integers greater than 1. First, Christine chooses a number, then Matt chooses a number, then Christine again, and so on. The following rules restrict how new numbers may be chosen by the two players:

A number which has already been selected by Christine or Matt, or a multiple of such a number,cannot be chosen.
A sum of such multiples cannot be chosen, either.

If a player cannot choose any new number according to these rules, then that player loses the game.
Here is an example: Christine starts by choosing 4. This prevents Matt from choosing 4, 8, 12, etc.Let’s assume that his move is 3. Now the numbers 3, 6, 9, etc. are excluded, too; furthermore, numbers like: 7 = 3+4;10 = 2*3+4;11 = 3+2*4;13 = 3*3+4;… are also not available. So, in fact, the only numbers left are 2 and 5. Christine now selects 2. Since 5=2+3 is now forbidden, she wins because there is no number left for Matt to choose.
Your task is to write a program which will help play (and win!) the Number Game. Of course, there might be an infinite number of choices for a player, so it may not be easy to find the best move among these possibilities. But after playing for some time, the number of remaining choices becomes finite, and that is the point where your program can help. Given a game position (a list of numbers which are not yet forbidden), your program should output all winning moves.
A winning move is a move by which the player who is about to move can force a win, no matter what the other player will do afterwards. More formally, a winning move can be defined as follows.

A winning move is a move after which the game position is a losing position.
A winning position is a position in which a winning move exists. A losing position is a position in which no winning move exists.
In particular, the position in which all numbers are forbidden is a losing position. (This makes sense since the player who would have to move in that case loses the game.)
Input

The input consists of several test cases. Each test case is given by exactly one line describing one position.
Each line will start with a number n (1 <= n <= 20), the number of integers which are still available. The remainder of this line contains the list of these numbers a1;…;an(2 <= ai <= 20).
The positions described in this way will always be positions which can really occur in the actual Number Game. For example, if 3 is not in the list of allowed numbers, 6 is not in the list, either.
At the end of the input, there will be a line containing only a zero (instead of n); this line should not be processed.
Output

For each test case, your program should output “Test case #m”, where m is the number of the test case (starting with 1). Follow this by either “There’s no winning move.” if this is true for the position described in the input file, or “The winning moves are: w1 w2 … wk” where the wi are all winning moves in this position, satisfying wi < wi+1 for 1 <= i < k. After this line, output a blank line.
Sample Input

2 2 5
2 2 3
5 2 3 4 5 6
0
Sample Output

Test Case #1
The winning moves are: 2

Test Case #2
There’s no winning move.

Test Case #3
The winning moves are: 4 5 6
Source

Mid-Central European Regional Contest 2000

题目的意思就是:有一个不到20的数列,两个人一次选择一个数字。选择完一个数字之后,这个数字的倍数,以及这个数字和前面选过的数字之和,都不可以再选。给你一串数列,问你有没有必胜的选择,就是当前选择这个数字之后,无论对方选择什么都是死!!

解题思路:非常像博弈的题目啊,可是这道题目的标签是状态压缩,当然不是我原创的,我一开始也不会啊,看来别人的博客才知道怎么去写。其实看别人博客,也是学习acm的必经之路,不是吗?只是看完之后你得有自己的思考!!
状态压缩:由于数列不到20,可以用二进制压缩,比如这样一个数列 2 3 5 那么二进制表示就是110100000….
这样的话,一个数列就可以用一个数字来表示。这就是状态压缩的好处,试想想,没有状态压缩,表示一个数列:234567891011… 或者用一个数组表示。。这些都太麻烦啦。
其次:状态压缩我是可以想到的,但是怎么解决这个问题呢,我一直在想动态规划,每个数列可以用0表示是必胜的数列,1表示不是必胜的数列,然后数列可以逐个递推!对,没错,思路是这样,但是你看代码,其实用深度优先搜索,并没有动态规划的形式,用搜索之所以可以,是因为记忆化搜索,即只要有一个状态确定是0或者1,那么就不用对它进行搜索,这样就会非常快。
动态规划的两种方式实现,一个是递推,另一个就是记忆化搜索。二者都是遍历了所有情况

关于状态压缩和位运算
http://blog.csdn.net/Dacc123/article/details/50974579

#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stdlib.h> using namespace std;
int dp[1<<20];
int n;
int a[25];
int s[25];
//这个函数是把这个二进制数列变成数字,就是将数列压缩成数字来
int getNum(int a[])
{
int res=0;
for(int i=2;i<=20;i++)
{
if(a[i])
res|=1;
res<<=1;
}
return res;
} int dfs(int s[],int st)
{
int v[25];
memcpy(v,s,25*sizeof(int));
v[st]=0;
//把i的倍数,与之前选过的数字之和,都标记成0
for(int i=2;i+st<=20;i++)
{
if(!v[i])
v[i+st]=0;
}
int ss=getNum(v);
//记忆化搜索,这里大幅度提高效率
if(dp[ss]!=0)
{
if(dp[ss]>0)
return 1;
else
return 0;
}
for(int i=2;i<=20;i++)
{
if(v[i]&&!dfs(v,i))
{
dp[ss]=1;
return 1;
}
}
dp[ss]=-1;
return 0;
}
int main()
{
int ans[25];
int b;
memset(dp,0,sizeof(dp));
int cas=0;
while(scanf("%d",&n)!=EOF)
{
cas++;
memset(a,0,sizeof(a));
if(n==0)
break;
for(int i=0;i<n;i++)
{
scanf("%d",&b);
a[b]=1;
}
int tot=0;
for(int i=2;i<=20;i++)
{
if(a[i]&&!dfs(a,i))
ans[tot++]=i;
}
printf("Test Case #%d\n",cas);
if(tot==0)
{
printf("There's no winning move.\n"); }
else
{
printf("The winning moves are: ");
for(int i=0;i<tot;i++)
{
if(i!=tot-1)
printf("%d ",ans[i]);
else
printf("%d\n",ans[i]);
}
}
printf("\n"); }
return 0;
}

POJ-1143(状态压缩)的更多相关文章

  1. poj 3254(状态压缩+动态规划)

    http://poj.org/problem?id=3254 题意:有一个n*m的农场(01矩阵),其中1表示种了草可以放牛,0表示没种草不能放牛,并且如果某个地方放了牛,它的上下左右四个方向都不能放 ...

  2. POJ 1185 状态压缩DP(转)

    1. 为何状态压缩: 棋盘规模为n*m,且m≤10,如果用一个int表示一行上棋子的状态,足以表示m≤10所要求的范围.故想到用int s[num].至于开多大的数组,可以自己用DFS搜索试试看:也可 ...

  3. POJ 1185 状态压缩DP 炮兵阵地

    题目直达车:   POJ 1185 炮兵阵地 分析: 列( <=10 )的数据比较小, 一般会想到状压DP. Ⅰ.如果一行10全个‘P’,满足题意的状态不超过60种(可手动枚举). Ⅱ.用DFS ...

  4. poj 1324 状态压缩+bfs

    http://poj.org/problem?id=1324 Holedox Moving Time Limit: 5000MS   Memory Limit: 65536K Total Submis ...

  5. poj 2923(状态压缩dp)

    题意:就是给了你一些货物的重量,然后给了两辆车一次的载重,让你求出最少的运输次数. 分析:首先要从一辆车入手,搜出所有的一次能够运的所有状态,然后把两辆车的状态进行合并,最后就是解决了,有两种方法: ...

  6. poj 2688 状态压缩dp解tsp

    题意: 裸的tsp. 分析: 用bfs求出随意两点之间的距离后能够暴搜也能够用next_permutation水,但效率肯定不如状压dp.dp[s][u]表示从0出发訪问过s集合中的点.眼下在点u走过 ...

  7. Mondriaan's Dream(POJ 2411状态压缩dp)

    题意:用1*2的方格填充m*n的方格不能重叠,问有多少种填充方法 分析:dp[i][j]表示i行状态为j时的方案数,对于j,0表示该列竖放(影响下一行的该列),1表示横放成功(影响下一列)或上一列竖放 ...

  8. poj 2411 状态压缩dp

    思路:将每一行看做一个二进制位,那么所有的合法状态为相邻为1的个数一定要为偶数个.这样就可以先把所有的合法状态找到.由于没一层的合法状态都是一样的,那么可以用一个数组保存.由第i-1行到第i行的状态转 ...

  9. poj 3254 状态压缩DP

    思路:把每行的数当做是一个二进制串,0不变,1变或不变,找出所有的合法二进制形式表示的整数,即相邻不同为1,那么第i-1行与第i行的状态转移方程为dp[i][j]+=dp[i-1][k]: 这个方程得 ...

  10. POJ 2411 状态压缩递,覆盖方案数

    无非就是横着放与竖着放,状态中用1表示覆盖,0表示未覆盖. #include <iostream> #include <vector> #include <algorit ...

随机推荐

  1. RabbitMQ ——“Hello World”

    介绍 RabbitMQ是一个消息实体服务(broker):它接收及转发消息.你可以把它想象成一个邮局:当你把你想要寄送的邮件放进邮箱里时,你能够确信邮局的派送员最终会把你的这封邮局送到这信的收件者手中 ...

  2. [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:Hello ...

  3. lua -- 在弹框中显示物品列表

    -- 宝箱打开后,显示里面的物品列表 -- 显示方式是:一个一个显示,每三个一行,一行显示完就移动到下一行, -- 接下来的一样要显示框的中间位置,方便玩家看 function UIBagContro ...

  4. [Big Data - Kafka] Kafka设计解析(四):Kafka Consumer解析

    High Level Consumer 很多时候,客户程序只是希望从Kafka读取数据,不太关心消息offset的处理.同时也希望提供一些语义,例如同一条消息只被某一个Consumer消费(单播)或被 ...

  5. ECMAScript 6 入门之新的数据类型Symbol

    1.Symbol,一个每次创建都不一样的值 Symbol undefined null Boolean String Number Object let c=Symbol("这是一个Symb ...

  6. 比Screen更好用的神器:tmux

    安装并启动 tmux tmux 应用程序的名称来源于终端(terminal)复用器(muxer)或多路复用器(multiplexer).换句话说,它可以将您的单终端会话分成多个会话. 它管理窗口和窗格 ...

  7. Hack mind

    试 卷 姓名________ 学号________ 首先我们来看这个,试卷的名字和编号填写,这个部分有“漏洞”吗?有 学生的姓名和编号都写在这儿,没有做任何保护措施,因此,你只要偷看了某人的试卷上的这 ...

  8. JVM内存管理及垃圾回收【转】

    很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...

  9. CentOS配置Tomcat开机启动

    通常我们进行服务器维护的时候需要注意点为,服务器上的容器一般都是开机启动,减少停机后应用还需要一个一个启动的麻烦. 1) 新建tomcat文件 touch /etc/rc.d/init.d/tomca ...

  10. Amazon

    刚接到Recruiter电话,说恭喜,feedback都非常好. 心里大石落地,FLAG / UAT终于完成一家. 接下来就要加倍努力冲刺其他公司了. Mark: (入职以后一定要去地里补发一波面经, ...