题解
题目意思 给你n个回合轮流出牌 A先手 A想让分数大于等于k B想让分数小于等于l
在双方都足够聪明的情况下 最终结果是大于k还是小于l
按照题意初始化n+1回合 大于等于k(1)小于等于l(-1)还是l和k之间(0)
d[i][j] 表示第i回合 分数为j的情况
倒着回合 枚举每个状态 负值用100往上的下标表示
A出牌的时候让结果尽量大(取max) B让结果尽量小(取min) 最后d[1][(m的正确下标)]为答案
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e3 + 10;
const int MAXM = 2e2 + 10;
int d[MAXN][MAXM];
int a[MAXN], b[MAXN], c[MAXN];
int cal(int x)
{
x = min(max(x, -100), 100);
if (x < 0)
x = -x + 100;
return x;
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
memset(d, 0x3f, sizeof(d));
int n, m, k, l;
cin >> n >> m >> k >> l;
for (int i = 1; i <= n; i++)
scanf("%d%d%d", &a[i], &b[i], &c[i]);
for (int i = 0; i <= 200; i++) //n+1回合为结束
{
int v = i; //真正值
if (v > 100)
v = -(v - 100);
if (v >= k)
d[n + 1][i] = 1;
else if (v <= l)
d[n + 1][i] = -1;
else
d[n + 1][i] = 0;
}
for (int i = n; i >= 1; i--) //第几轮
{
for (int j = 0; j <= 200; j++) //值下标
{
int v = j, fst = 1; //真正值
if (v > 100)
v = -(v - 100);
if (i & 1) //好
{
if (a[i] && d[i + 1][cal(v + a[i])] != INF)
{
if (fst)
d[i][j] = d[i + 1][cal(v + a[i])];
else
d[i][j] = max(d[i][j], d[i + 1][cal(v + a[i])]);
fst = 0;
}
if (b[i] && d[i + 1][cal(v - b[i])] != INF)
{
if (fst)
d[i][j] = d[i + 1][cal(v - b[i])];
else
d[i][j] = max(d[i][j], d[i + 1][cal(v - b[i])]);
fst = 0;
}
if (c[i] && d[i + 1][cal(-v)] != INF)
{
if (fst)
d[i][j] = d[i + 1][cal(-v)];
else
d[i][j] = max(d[i][j], d[i + 1][cal(-v)]);
}
}
else //坏
{
if (a[i] && d[i + 1][cal(v + a[i])] != INF)
{
if (fst)
d[i][j] = d[i + 1][cal(v + a[i])];
else
d[i][j] = min(d[i][j], d[i + 1][cal(v + a[i])]);
fst = 0;
}
if (b[i] && d[i + 1][cal(v - b[i])] != INF)
{
if (fst)
d[i][j] = d[i + 1][cal(v - b[i])];
else
d[i][j] = min(d[i][j], d[i + 1][cal(v - b[i])]);
fst = 0;
}
if (c[i] && d[i + 1][cal(-v)] != INF)
{
if (fst)
d[i][j] = d[i + 1][cal(-v)];
else
d[i][j] = min(d[i][j], d[i + 1][cal(-v)]);
}
}
}
}
if (m < 0)
m = -m + 100;
if (d[1][m] == 1)
cout << "Good Ending" << endl;
else if (d[1][m] == -1)
cout << "Bad Ending" << endl;
else
cout << "Normal Ending" << endl;
return 0;
}