加载中...

子序列求选择最大值

连续的子序列的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;
}
posted @ 2022-09-06 21:55  liang302  阅读(44)  评论(0编辑  收藏  举报