Embiid  

2020 CCPC-Wannafly Winter Camp Day6 ---I. 变大!

最后的答案一定是一段一段的,每段有一个最大值。
我们考虑将某一段全变成最大值需要的次数,每一次操作能将2个数变成最大值,所以一段长为L的全部变成最大值需要L/2次。
f[i][j]表示前i个数操作j次后的最大和。
考虑最后一段长度为k,则有\(f[i][j] = MAX(f[i - k + 1][j - k / 2] + maxx * k)\)

#include <bits/stdc++.h>
using namespace std;

int f[55][55];
int a[55];

int main() {
	int t;
	scanf("%d" , &t);
	while (t--) {
		memset(f , 0 , sizeof(f));
		int n;
		scanf("%d" , &n);
		for (int i = 1; i <= n; i++) scanf("%d" , &a[i]);
		for (int i = 1; i <= n; i++){
			int maxx = 0;
			for (int j = i; j >= 1; j--) {
				maxx = max(maxx , a[j]);
				int p = (i - j + 1) / 2;
				for (int k = p; k <= n; k++)
					f[i][k] = max(f[i][k] , f[j - 1][k - p] + maxx * (i - j + 1));
			}
		}
		for (int i = 1; i <= n; i++) printf("%d%s" , f[n][i] , i == n ? "\n" : " ");
	}
} 

posted on 2020-02-06 22:04  Embiid  阅读(164)  评论(0编辑  收藏  举报