#include <bits/stdc++.h>
using namespace std;
using VI = vector<int>;
using PII = pair<int,int>;
using ll = long long;
using ull = unsigned long long;
int s,m,n;
/*
* 只能跑一种方案
* 第i座城堡获得i分
* dp[i][x] 第i作城堡,派遣 x 名 能获得的最大分数
* */
int val[110][2000010];
int v[110][110];
int sct[110];
int dp[200010] = {0};
int f(int t,int num){
int ct = 0;
for(int i=1;i<=s;i++){
if(num > 2 * v[i][t]){
ct += t;
}
}
return ct;
}
int w[110][110];
int main(){
vector<int > q[110];
cin>>s>>n>>m;
for(int i=1;i<=s;i++){
for(int j=1;j<=n;j++){
int x;
cin>>x;
q[j].push_back(x);
}
}
for(int i=1;i<=n;i++){
sort(q[i].begin(),q[i].end());
//cout<<q[i].size();
int ct = 0;
for(int j=0;j<q[i].size();j++){
if( 2 * q[i][j] + 1 <= m){
ct++;
w[i][ct] = 2 * q[i][j] + 1;
while(q[i][j] == q[i][j+1] && j+1<q[i].size()) j++;
v[i][ct] = (j + 1) * i;
}else{
break;
}
}
sct[i] = ct;
}
for(int i=1;i<=n;i++){
for(int j=m;j>=0;j--){
for(int k=1;k<=sct[i];k++){
if(j >= w[i][k]){
dp[j] = max(dp[j],dp[j - w[i][k]] + v[i][k]);
}
}
}
}
cout<<dp[m];
}
分组背包,就是得自己造物品的重量和价值,并不算太复杂吧
双指针找相同元素时注意 j + 1 别越界