SOL
乍一看你可能jio得这是一个贪心+模拟
如果是这样的话,显然你想多了
我们发现这应该是一个DP,再看看题目,存在兵力上限,那就相当于背包容积咯,那就是分组背包咯
可是也没这么轻易就让你A了,直接转移是不行的,我们可以贪心发现你打第
i
i
i个碉堡时如果想打爆最弱的
j
j
j个玩家,用
2
∗
a
j
+
1
2*aj+1
2∗aj+1个兵显然是最优的,对原数组排一个序,就成为了我们可以使用的物品
代码:
#include<bits/stdc++.h>
using namespace std;
#define re register
inline char nc(){
static char buf[10000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,10000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
int re data=0;char ch=0;ch=nc();
while(!isdigit(ch))ch=nc();
while(isdigit(ch))data=(data<<1)+(data<<3)+(ch^48),ch=nc();
return data;
}
const int M=2e4+5,N=105;
int s,n,m,f[N][M],a[N][N];
signed main(){
s=rd(),n=rd(),m=rd();
for(int re i=1;i<=s;++i)
for(int re j=1;j<=n;++j)
a[j][i]=rd()<<1|1;
for(int re i=1;i<=n;++i)sort(a[i]+1,a[i]+s+1);
for(int re i=1;i<=n;++i){
for(int re j=0;j<=s;++j)
for(int re k=m;k>=a[i][j];--k)
f[i][k]=max(f[i][k],f[i-1][k-a[i][j]]+j*i);
}
cout<<f[n][m];
exit(0);
}