我们用记搜方式实现。
当$all=0$时,直接返回0。
当$all\not=0$时,我们枚举取的个数,从中选出最大值。
一些边界、细节请看代码。
# 代码
```cpp
#include<bits/stdc++.h>
using namespace std;
int n, m;
int a[205][205][205];
int SG( int all, int one, int tho ){
if ( all == 0 ) return 0;
if ( a[all][one][tho] ) return a[all][one][tho];
int ans(0);//ans为找出的最大值
for ( int i = 1; i <= min( m, all - one - tho ); ++i ){
if ( one + tho + i == all ) ans = max( ans, all - SG( tho, 0, 0 ) );//取完了,把没取到最后一个甜甜圈的人的甜甜圈拿来继续取
else ans = max( ans, all - SG( all, tho, one + i ) );//没取完,继续取
}
return a[all][one][tho] = ans;//记录答案
}
int main(){
int T;
scanf( "%d", &T );
while( T-- ){
memset( a, 0, sizeof a );//每次的m都不同,所以别忘了初始化
scanf( "%d%d", &n, &m );
printf( "%d\n", SG( n, 0, 0 ) );
}
return 0;
}
```