#include <iostream>
using namespace std;
//评论: 算法1效率底下,是因为重复计算相同的值,而动态规划将浪费大量的时间计算不需要的中间值
//可以结合这两者的优点,得出算法3
// 游戏规则:n个棋子,两个人轮流取,最后一次取完者赢。当前取得棋子数量在1到2*k(k: 对手在上步取的数量)
////算法1
int min(int a, int b)
{
if(a<b)
return a;
return b;
}
bool recwin(int i, int j) // 1<=j<=i 重复的计算,效率底下
{
if(i==0)
return false;
if(i==j)
return true;
for(int k=1; k<=j;k++)
{
if ( !recwin(i-k, min(i-k, 2*k) ) )
return true;
}
return false;
}
/////算法2,动态规划
bool G[11][11];
void dynwin(int n) //对于目标值来说,计算了太多不必要的中间值
{
G[0][0]= false;
int k;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
k=1;
while(k<j)
{
if( G[i-k][min(2*k,i-k)] )
k++;
else{
G[i][j] = true;
break;
}
}
if(k==j)
G[i][j] = false;
}
}
}
//算法3/////
bool know[11][11];
void init3()
{
G[0][0] = false;
know[0][0] =true;
for(int i=1;i<=11;i++)
{
for(int j=1;j<=i;j++)
{
know[i][j] =false;
}
}
}
bool nim(int i, int j) //:) 中和了动态规划和递归两方面的优点
{
init3();
if(know[i][j] == true)
return G[i][j];
know[i][j] =true; //本函数将计算出来G[i][j],所以这步可以取true
for(int k=1;k<=j;k++)
{
if( !nim( i-k, min(2*k,i-k) ) )
{
G[i][j] = true;
return true;
}
}
G[i][j] =false;
return false;
}
void test1()
{
for(int i=1; i<10;i++)
{
cout<<"i=="<<i<<" j==";
for(int j=1; j<=i; j++)
{
if(recwin(i,j))
cout<<j<<"-win"<<" ";
else
cout<<j<<"-lose"<<" ";
}
cout<<endl;
}
}
void test2()
{
dynwin(11);
for(int j=1;j<=11;j++)
{
cout<<" "<<j;
}
cout<<endl;
for(int i=1; i<=11;i++)
{
cout<<i;
for(j=1;j<=i;j++)
{
if(G[i][j])
cout<<" w";
else
cout<<" l";
}
cout<<endl;
}
}
int main()
{
test2();
return 0;
}