P5322 排兵布阵(分组背包基础)

  • 我会暴力!
    可以先 \(O(nm+ns\log s)\) 预处理每一座城堡兵力对应收益。
    然后跑 \(O(nm^2)\) 的暴力 DP。
  • 我有脑子!
    发现每一座城堡对应最多 \(s\) 个有效转移点。
    仅仅转移这些转移点,应该能够做到 \(O(nms)\)
    发现等价于一个分组背包。

不能拆分成 01,因为人攻占一个城堡并不会减少。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=109,M=20009;
int s,n,V,cost[N][N],f[M];
int main(){
    scanf("%d%d%d",&s,&n,&V);
    for(int i=1;i<=s;i++) for(int j=1;j<=n;j++)
        scanf("%d",&cost[j][i]),cost[j][i]*=2,++cost[j][i];
    for(int i=1;i<=n;i++) sort(cost[i]+1,cost[i]+s+1);
    for(int i=1;i<=n;i++) for(int j=V;j>=1;j--) for(int k=1;k<=s&&cost[i][k]<=j;k++)
        f[j]=max(f[j],f[j-cost[i][k]]+i*k);
    printf("%d\n",f[V]);
    return 0;
}
posted @ 2026-02-14 23:29  2025ing  阅读(0)  评论(0)    收藏  举报