设为首页 加入收藏

TOP

dp+博弈 uva-10404-Bachet's Game
2015-11-21 01:13:56 来源: 作者: 【 】 浏览:1
Tags:博弈 uva-10404-Bachet' Game
?
题目意思:
给你石头的数量n,然后给你m个数,每个数表示每次可以拿的石头的数量,其中一定有一个数为1。
有两个人玩游戏,依次从石头堆里取上面m个数中的一个,拿走该数量的石头,最后拿完石头的那个人赢,问谁赢。每个人每一步都是朝最有利于自己赢的数量拿。
?
解题思路:
看成是一个dp问题,dp[i]=1表示当有i个石头时,先拿的人赢,dp[i]=2表示先拿的人输。
依次对m个可拿的石头数量试探,当有一种拿法使得去掉该数量石头后是先负状态,则此状态为先赢状态。实际上是一个博弈问题。www.2cto.com
由于n很大,用递归的话,每次保存现场,占用的空间会超,但题目限制时间为6s所以可以用递推代替递归,用时间换空间。
?
代码:
[cpp] ?
#include ?
#include ?
#include ?
#include ?
#include ?
#include ?
#include ?
#include ?
#include ?
#include ?
#include ?
#define eps 1e-6 ?
#define INF (1<<20) ?
#define PI acos(-1.0) ?
using namespace std; ?
??
??
int ?dp[1200000]; //dp[i]=1表示先胜状态,dp[i]=2表示先负状态,dp[i]=0表示还没有确定 ?
int kind[15],n,m; ?
??
/*int dfs(int temp) ?//既然时间给了6s,可以用时间换空间,用递推代替递归?
{?
?
? ? if(dp[temp])?
? ? ? ? return dp[temp];?
?
? ? for(int i=1;i<=m&&kind[i]<=temp;i++)?
? ? ? ? if(dfs(temp-kind[i])==2)?
? ? ? ? ? ? return dp[temp]=1;?
?
? ? return dp[temp]=2;?
}*/ ?
??
int main() ?
{ ?
? ? while(scanf("%d",&n)!=EOF) ?
? ? { ?
? ? ? ? scanf("%d",&m); ?
? ? ? ? for(int i=1;i<=m;i++) ?
? ? ? ? { ?
? ? ? ? ? ? scanf("%d",&kind[i]); ?
? ? ? ? ? ? dp[kind[i]]=1; //直接设为先胜,免得以后考虑 ?
? ? ? ? } ?
? ? ? ? sort(kind+1,kind+m+1); ?
? ? ? ? memset(dp,0,sizeof(dp)); ?
? ? ? ? dp[0]=2; ?
? ? ? ? for(int i=1;i<=n;i++) //改成递推就过了,哈哈,递归保存现场占用好多空间 ?
? ? ? ? { ?
? ? ? ? ? ? int flag=0; ?
? ? ? ? ? ? for(int j=1;j<=m&&kind[j]<=i;j++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? ?if(dp[i]==0&&dp[i-kind[j]]==2) ?
? ? ? ? ? ? ? ? ?{ ?
? ? ? ? ? ? ? ? ? ? ?flag=1; ?
? ? ? ? ? ? ? ? ? ? ?break; ?
? ? ? ? ? ? ? ? ?} ?
? ? ? ? ? ? } ?
? ? ? ? ? ? flag?dp[i]=1:dp[i]=2; ?
? ? ? ? } ?
??
? ? ? ? //int ans=dfs(n); ?
??
? ? ? ? dp[n]==1?printf("Stan wins\n"):printf("Ollie wins\n"); ?
? ? } ?
??
? ? return 0; ?
} ?
?
?
?
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇字符串系列――10010 Where's.. 下一篇HDU1037:Keep on Truckin'

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: