[AtCoder - tdpc_game] :ゲーム 题解

[AtCoder - tdpc_game] :ゲーム 题解

一道小清新 dp 题。

定义 dpi,j 为第一堆山还有 i 个物品,第二堆山还有 j 个物品,すぬけ君能取得物品的最大价值。

由于只能取两座山最上面的物品,假设当前两座山分别有 x,y 个物品,すぬけ君选后只能有两种情况,分别为 dpi1,jdpi,j1。可增加的价值分别为 aibj

他想让自己的答案尽量大,应取 max

现在该另一人选择,他取了物品后将会有 3 种情况,分别为 dpi2,jdpi1,j1dpi,j2

3 种情况怎么来的?现在有 dpi1,jdpi,j1 两种情况,另一人在两座山中再选物品。

那么,由 dpi1,j 可推出 dpi11,j=dpi2,jdpi1,j1

同理,由 dpi,j1 可推出 dpi1,j1dpi,j11=dpi,j2

整理可得以上 3 种情况了。

但是,由于两人都同样聪明,他会让すぬけ君接下来的答案尽量小。

所以应该以上两种情况分别取 min

整的转移式为 dpi,j=max(ai+min(dpi1,j1,dpi2,j),bj+min(dpi1,j1,dpi,j2))

好了,此题就结束了。

最后贴上代码:

#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;
}
posted @   云岚天上飘  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

阅读目录(Content)

此页目录为空

喜欢请打赏

扫描二维码打赏

了解更多

点击右上角即可分享
微信分享提示