子序列求选择最大值
连续的子序列的m个数 使得第i个数*a[i] 最终得到的值最大
https://atcoder.jp/contests/abc267/tasks/abc267_c
前缀和 + 滑动窗口 转移之间相差一个前缀和 和 a[m]*m
vector<LL> a(n + 1, 0);
LL ans = -1e18;
LL sum = 0;
LL tmp = 0;
for(int i = 1; i <= n; ++ i){
cin >> a[i];
if (i <= m){
sum += a[i];
tmp += a[i] * i;
}else{
ans = max(ans, tmp);
tmp -= sum;
sum -= a[i - m];
sum += a[i];
tmp += a[i] * m;
}
}
ans = max(ans, tmp);
选择子序列 非连续 要求给定一个序列A,找一长度为 m的(不连续)子序列B,其 \(\sum\limits_{i=1}^{m} i \times B_i\)值最大,求该最大值。
设dp[i][j]表示前 i个数选了 j个数的最大值,对于第i+1个数考虑选或不选转移即可。
signed main(){
int n,m;
cin>>n>>m;
vector<vector<int>> f(n + 1, vector<int>(m + 1, -1e18));
int res=-1e18;
f[0][0]=0;
for(int i=1;i<=n;i++){
int x;cin>>x;
f[i][0]=0;
for(int j=1;j<=min(i,m);j++){
f[i][j]=max(f[i-1][j],f[i-1][j-1]+j*x);
}
}
for(int i=1;i<=n;i++){
res=max(res,f[i][m]);
}
cout<<res;
return 0;
}