题目链接:https://ac.nowcoder.com/acm/contest/886/J
题意:有n个技能,每个技能有m个等级,对于第i个技从j-1升级到j等级需要消耗 a[i][j] ,如果所有的技能都升级到j等级,会有p[j]的奖励。对于所有技能可以不升级。求升级某些技能,使得这个人的收益最多。
解析:刚开始做这道题的时候,想到做法,可能有越想越偏,最后被队友给做出来了。 我们假设第 i 个技能的第j个等级是所有技能里面等级最小的。那么对于剩下的所有技能的等级就是从 j ~ m里面选择消耗最小的。枚举所有情况找到收益最大的即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int Maxn = 1500;
int T , n , m;
ll a[Maxn][Maxn];
ll sum[Maxn] , maxn[Maxn][Maxn]; //maxn[i][j] 存的是第i种技能的等级从j到m的收益最大值
ll ans , x ;
int t;
int main(){
scanf("%d",&T);
while(T--){
ans = 0;
memset(sum , 0, sizeof(sum));
memset(maxn , 0 ,sizeof(maxn));
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
scanf("%lld",&a[i][j]);
a[i][j] *= -1;
sum[j] += a[i][j];
}
}
for(int j = 1;j <= m;j++){
scanf("%lld",&x);
sum[j] += sum[j-1]+ x;
}
for(int i = 1;i <= n;i++){
maxn[i][m] = a[i][m];
sum[m-1] += max( 0ll , a[i][m]);
for(int j = m - 1;j >= 1;j--){
maxn[i][j] = max(maxn[i][j + 1] + a[i][j] , a[i][j] );
sum[j - 1] += max(0ll , maxn[i][j]);
}
}
for(int i = 1;i <= n;i++){
for(int j = 0;j <= m;j++){
ans = max(ans , sum[j ] - max(maxn[i][j+1] , 0ll));
}
}
printf("Case #%d: %lld\n",++t,ans);
}
}