题意:取石子游戏,第二个人取的石子<=前一个人*2,没有石子取的输。 问赢的人第一步最少取几个石子
用dfs()打表发现必败的状态满足斐波那契数列
求第一步最少取几个石子:不是 n-最近的斐波那契数,因为这样不是最小的,
发现第一阶段应取完 n-最近的斐波那契数 这么多的石子,这就成了一个递归的问题,出口为 n-最近的斐波那契数==一个 斐波那契数(因为不一次取完这些就会输)
打表的程序 (在网上抄的)
#include<iostream>
#include<cstdlib>
#include<stdio.h>
using namespace std;
int dfs(int x,int pre) //返回0代表输
{
if(x==0) return 0;
for(int i=1;i<=2*pre;i++)
{
if(x-i<0) break;
if(dfs(x-i,i)==0)
return 1;
}
return 0;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
bool flag=true;
for(int i=1;i<n;i++)
{
if(dfs(n-i,i)==0)//先手拿了i个后
{
puts("YES");
flag=false;
break;
}
}
if(flag)
puts("NO");
}
}
正确的程序
#include<iostream>
#include<cstring>
using namespace std;
int a[100];
void get()
{
a[0]=1;
a[1]=2;
a[2]=3;
for(int i=3;i<40;i++)
{
a[i]=a[i-1]+a[i-2];
//cout<<a[i]<<endl;
}
}
int solve(int n)
{
for(int i=0;i<50;i++)
{
if(a[i]>n) return a[i-1];
}
}
int main()
{
get();
int n;
while(cin>>n)
{
int ans=0;
int now,last;
if(n==0||n==2||n==3)
{
cout<<"lost"<<endl;
continue;
}
ans=solve(n);
if(ans==n) cout<<"lost"<<endl;
else
{
while(ans!=n)
{
n=n-ans;
ans=solve(n);
}
cout<<ans<<endl;
}
}
}