题意#
一个游戏,有 座城堡,每局对战有两名玩家,每名玩家有 个士兵,每人可以向第 个城堡派遣 名士兵,士兵总数满足:.
二人争夺这些城堡,如果一名玩家向城堡 派遣的士兵数严格大于对手士兵数的两倍,那么这名玩家占领了这座城堡,获得 分。
现给定 名玩家及其各自的派兵策略,你需要选定一个固定的派兵策略,最大化你在 场游戏中的总得分。
.
分析#
考虑DP。
设 表示:对于前 个城堡共派出 个士兵;设 表示:在城堡 ,玩家 的出兵数量。
对每个城堡,把各个玩家在该城堡的出兵数量,按升序排序。
这样一来,若你在城堡 的出兵数量大于 ,则你可以在城堡 获得 的得分。
于是对每个赢得城堡 ,枚举要战胜前 个玩家,分别转移即可:
属于分组背包模型。
代码#
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 108, MAXM = 20008, MAXS = 108;
int s, n, m;
int dp[MAXM], a[MAXN][MAXS];//a[i][j]表示第i个城堡,第j个玩家
int main() {
scanf("%d%d%d", &s, &n, &m);
for(int i = 1; i <= s; i++)
for(int j = 1; j <= n; j++)
scanf("%d", &a[j][i]);
for(int i = 1; i <= n; i++)
sort(a[i] + 1, a[i] + s + 1);
for(int k = 1; k <= n; k++) {
for(int i = m; i > 0; i--) {
for(int j = 1; j <= s; j++) {
if(i >= a[k][j] * 2 + 1) {
dp[i] = max(dp[i], dp[i - a[k][j] * 2 - 1] + k * j);
}
}
}
}
cout << dp[m] << endl;
return 0;
}
cpp