因为看到这题目分类在分组背包下,所以一直在试图抽象出分组背包的模型来……最后很接近答案了,对于第(i)座城堡所有玩家的出兵数量视为一组物品……再想到分组背包的板子,应该每组只能挑一个物品。但是结合题目,挑的物品不一样收益也不一样,这个收益该怎么计算卡住了我……
看题解才恍然,直接对第(i)座城堡各个玩家的出兵数量排个序就完事了,这样挑了一个数量之后,收益就是小于这个数量的个数乘上(i),就这么简单。
const int maxn = 2e4 + 10;
int dp[maxn];
int cost[110][110], v[110];
bool cmp(int a, int b) {
return a > b;
}
int main()
{
//ios::sync_with_stdio(false);
//while (scanf("%d%d",&n,&m)!=EOF){
int s, n, m;
cin >> s >> n >> m;
for (int i = 1; i <= n; i++) v[i] = i;
for (int i = 1; i <= s; i++) {
for (int j = 1; j <= n; j++) {
cin >> cost[j][i];
if (cost[j][i]) cost[j][i] = cost[j][i] * 2 + 1;
else cost[j][i] = 1;
}
}
for (int i = 1; i <= n; i++) sort(cost[i] + 1, cost[i] + 1 + s, cmp);
//一开始写成了cost[i]+1+n……
for (int i = 1; i <= n; i++) {
//枚举组
for (int j = m; j >= 0; j--) {
//枚举容量
for (int k = 1; k <= s; k++) {
//枚举组内物品
if (j >= cost[i][k]) dp[j] = max(dp[j], dp[j - cost[i][k]] + (s - k + 1) * v[i]);
}
}
}
cout << dp[m];
return 0;
}