背包 ( exttt{dp})
把城堡看成为物品,派出的兵力为代价,获胜的场数乘上第几个城堡为价值。
记 (dp[i]) 表示已经派出 (i) 的兵力的最大价值。
那么我们考虑将每个人派出的兵力排序,枚举城堡 (i),由于已经排好序,能打败第 (k) 个敌人就能打败第 (k-1) 个,所以枚举敌人 (k),贪心地派出刚好比他的兵力两倍多 (1) 的兵力。
#include <bits/stdc++.h>
#define reg register
#define ll long long
#define ull unsigned long long
#define debug(typ...) fprintf(stderr,typ)
using namespace std;
int fastin() {
reg int x=0,ch=getchar(),f=0;
while(!isdigit(ch)) (ch=='-')&&(f=1),ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int MAXN=110;
const int MAXM=2e4+10;
int s,n,m,dp[MAXM],a[MAXN][MAXN];
void work() {
s=fastin(),n=fastin(),m=fastin();
for(reg int i=1;i<=s;++i) for(reg int j=1;j<=n;++j) a[j][i]=fastin();
for(reg int i=1;i<=n;++i) sort(a[i]+1,a[i]+s+1);
for(reg int i=1;i<=n;++i) for(reg int j=m;j>=0;j--) for(reg int k=1;k<=s;++k)
if(j>a[i][k]*2) dp[j]=max(dp[j],dp[j-a[i][k]*2-1]+i*k);
int ans=0;
for(reg int i=0;i<=m;++i) ans=max(ans,dp[i]);
printf("%d
",ans);
}
signed main() {
int _=1;
// _=fastin();
while(_--) {
work();
}
return 0;
}