hdu 2516 取石子游戏 Fibonacci Nim

1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜.先取者负输出"Second win".先取者胜输出"First win".

取石子游戏

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3807    Accepted Submission(s): 2272


Problem Description
1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜.先取者负输出"Second win".先取者胜输出"First win".
 

Input
输入有多组.每组第1行是2<=n<2^31. n=0退出.
 

Output
先取者负输出"Second win". 先取者胜输出"First win". 
参看Sample Output.
 

Sample Input
  
  
2 13 10000 0
 

Sample Output
  
  
Second win Second win First win
 

Source
 



首先试图找规律,我竟然用纸笔找规律,弄了半天发现完全不行,情况实在太复杂,开始用DP机器打表,

立马找到规律。


找规律代码:其中DP(limit,x)表示现在剩下x个,根据上一次取的数量确定这次最多取limit个。


#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int dp[1020][1020];
bool DP(int limit,int x)
{
    limit=min(limit,x);
    if(~dp[limit][x])  return dp[limit][x];
    dp[limit][x]=0;
    for(int i=1;i<=limit;i++)
    {
        dp[limit][x]|= !DP( 2*i,x-i);
    }
    return dp[limit][x];
}

int main()
{
    memset(dp,-1,sizeof dp);
   for(int i=2;i<=100;i++)
   {
     if(!DP(i-1,i))  printf("second: %d \n",i);
   }

   return 0;
}


运行结果:只输出second win 的






AC代码:

这个解法一直有一个困惑:为什么G++会提示超内存,而用C++内存使用少得可怜?

/**==========================================
 *   This is a solution for ACM/ICPC problem
 *
 *   @source: hdu 2516
 *   @type:
 *   @author: wust_ysk
 *   @blog:  http://blog.csdn.net/yskyskyer123
 *   @email: 2530094312@qq.com
 *===========================================*/
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<set>
using namespace std;
int n;
set<int >se;

void pre()
{
    se.insert(2);
    se.insert(3);
    int a=2,b=3;
    while(a+b>=0)
    {
        se.insert(a+b);
        int t=b;
        b=a+b;
        a=t;

    }
}

int main()
{
    pre();
   while(~scanf("%d",&n)&&n)
   {
       puts(se.count(n)?"Second win":"First win");
   }


   return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值