http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1168
Alice and Bob合作完成一个游戏,首先有n个石子,alice每次只能移动2的倍数多的石子,bob只能移动3的倍数多的石子,每次至少移动一个。alice先来,问至少需要多少次操作才能移完这些石子。
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10010;
const int inf = 999999999;
int dp[N][2];//定义两种状态,dp[i][0]表示alice的移动数量为i的石子的最小移动次数,dp[i][1]表示 bob表示移动数量为i的石子的最小移动次数,
int a[20], b[20];
int main()
{
a[0] = b[0] = 1;
for(int i = 1; i <= 16; i++)//算出前16项就满足题目要求
a[i] = a[i-1]*2, b[i] = b[i-1]*3;
int T, n;
scanf("%d", &T);
while( T-- )
{
scanf("%d", &n);
dp[0][0] = dp[0][1] = 0;//移动数量为0的石子移动次数为0
for(int i = 1; i <= n; i++)
{
int t = inf;
for(int k = 0; a[k] <= i; k++)//类似于背包求最小的构成i的方案,并赋值为t
t = min( t, dp[ i-a[k] ][1] );//要在bob的基础上,比较,因为alice和bob是轮流交换的,
dp[i][0] = t+1;//保存步数
t = inf;
for(int k = 0; b[k] <= i; k++)
t = min( t, dp[ i-b[k] ][0] );
dp[i][1] = t+1;
}
printf("%d\n", dp[n][0] );//alice先移完
}
return 0;
}