2019牛客暑期多校訓練營(第六場)J Upgrading Technology 後綴和

 題意:有i個技能,每次升級都有花費cij,然後所有技能都達到j級送dj塊錢,問你最多能賺多少

 解:先將花費乘-1轉換爲收益,對 a[i][j] 維護後綴和,表示 j+1~m 最大收益。

然後  j 從1 到 m 遍歷,j 表示當前某個技能的最低等級,找到 第 i 個技能 最小的後綴和,減去這個後綴和並加上其他技能的後綴和,再加上所以技能都達到 j 的收益取最大值。 

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll sum[1005][1005];
int d[1005];
int a[1005][1005];
int main() {
	int cnt=1,t,n,m;
	scanf("%d",&t);
	while(t--) {
		scanf("%d %d",&n,&m);
		for(int i=1; i<=n; i++)
			for(int j=1; j<=m; j++)scanf("%d",&a[i][j]),a[i][j]=-a[i][j];
		for(int i=1; i<=m; i++)scanf("%d",&d[i]);
		
		for(int i=1;i<=n;i++){
			sum[i][m] = 0;
			for(int j=m-1;j>=0;j--){
				sum[i][j] = max(0ll,sum[i][j+1]+a[i][j+1]);
			}
		}
		ll now = 0,ans = 0;
		for(int j=0;j<=m;j++){
			for(int i=1;i<=n;i++)now+=a[i][j];
			now+=d[j];
			ll tp = 0,mi = 1e18;
			for(int i=1;i<=n;i++)tp+=sum[i][j],mi = min(mi,sum[i][j]);
			ans = max(ans,tp-mi+now);
		}
		printf("Case #%d: %lld\n",cnt++,ans);
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章