n 個甜甜圈,每次取 1~m 個。Steve 和 Digit 輪流取,取完者吃掉自己手中甜甜圈,對手的甜甜圈重新放回。下一輪對手先手。求 Steve 最大能吃多少個。n,m ≤ 100。
`d[i][j][u][p]`:總共 i 個甜甜圈,剩 j 個未取,Steve 手中 u 個,下一步玩家 p (0=Steve, 1=Digit) 時,**Steve 最終能吃到的最大數**。
**Steve 回合 (p=0):**
**Digit 回合 (p=1):** 同理,Digit 手中 q = i-j-u。
#include
#include
using namespace std;
int d[103][103][103][2];
int main() {
int n, m;
while (~scanf("%d%d", &n, &m)) {
d[0][0][0][0] = d[0][0][0][1] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
int p = i - j; // 已取總數
for (int u = 0; u <= p; u++) {
int q = p - u; // Digit 手中數
// Steve 回合
int best = 0;
for (int v = 1; v <= m; v++) {
if (v > j) break;
if (v == j) best = max(best, i - d[i-u-v][i-u-v][0][1]);
else best = max(best, i - d[i][j-v][u+v][1]);
}
d[i][j][u][0] = best;
// Digit 回合
best = 0;
for (int v = 1; v <= m; v++) {
if (v > j) break;
if (v == j) best = max(best, i - d[i-q-v][i-q-v][0][0]);
else best = max(best, i - d[i][j-v][u][0]);
}
d[i][j][u][1] = best;
}
}
}
printf("%d\n", d[n][n][0][0]);
}
return 0;
}
博弈雙方目標對立,`d` 定義為 Steve 最終所得,轉移時用「總數 - 對手最優所得」體現零和博弈本質。