本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目链接:
codeforces.com/contest/164…
表示对一个数组中不同的k个元素做加
x操作,最后的最大字段和。 求
对数组a做前缀和
状态表示:
:子段长度为i - j + 1的最大子段和
状态转移:
这个用动态规划求解最大子段和,复杂度
f[0] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= i; j++)
f[i - j + 1] = max(f[i - j + 1], s[i] - s[j - 1]);
}
因为还有增强的个数,所以最后统计需要加上增强的个数。
假设增强了j次,统计最大子段的长度为i,那么最多增强次,在所有的情况中取最佳即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t--)
{
int n, x;
cin >> n >> x;
vector<int> a(n + 1), s(n + 1, 0);
for(int i = 1; i <= n; i++)
{
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
vector<int> f(n + 1, -1e9);
f[0] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= i; j++)
f[i - j + 1] = max(f[i - j + 1], s[i] - s[j - 1]);
}
for(int i = 0; i <= n; i++)
{
int res = 0;
for(int j = 0; j <= n; j++)
res = max(res, f[j] + min(i, j) * x);
cout << res << " \n"[i == n];
}
}
return 0;
}