[AtCoder - tdpc_game] :ゲーム 题解
1.ARC_069 D - Menagerie 题解2.CF1999F.Expected Median 题解
3.[AtCoder - tdpc_game] :ゲーム 题解
4.[USACO 2025 January Contest, Bronze] T3 Cow Checkups 题解[AtCoder - tdpc_game] :ゲーム 题解
一道小清新
定义
由于只能取两座山最上面的物品,假设当前两座山分别有
他想让自己的答案尽量大,应取
现在该另一人选择,他取了物品后将会有
这
那么,由
同理,由
整理可得以上
但是,由于两人都同样聪明,他会让すぬけ君接下来的答案尽量小。
所以应该以上两种情况分别取
整的转移式为
好了,此题就结束了。
最后贴上代码:
#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e3 + 10;
int n, m, a[N], b[N], dp[N][N];
inline ll dfs(int x, int y) {
if (!x && !y) return dp[x][y] = 0;
if (dp[x][y] != -1) return dp[x][y];
ll ret = 0, num = 1e18;
if (x >= 1 && y >= 1) num = min(num, dfs(x - 1, y - 1));
if (x >= 2) num = min(num, dfs(x - 2, y));
if (num == 1e18) num = 0;
ret = max(ret, a[x] + num);
num = 1e18;
if (x >= 1 && y >= 1) num = min(num, dfs(x - 1, y - 1));
if (y >= 2) num = min(num, dfs(x, y - 2));
if (num == 1e18) num = 0;
ret = max(ret, b[y] + num);
return dp[x][y] = ret;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= m; ++i)
cin >> b[i];
reverse(a + 1, a + n + 1);
reverse(b + 1, b + m + 1);
//注意翻转两个数组
memset(dp, -1, sizeof dp);
ll ans = dfs(n, m);
cout << ans << "\n";
// for (int i = 1; i <= n; ++i) {
// for (int j = 1; j <= m; ++j)
// cout << dp[i][j] << " ";
// cout << "\n";
// }
return 0;
}