Educational Codeforces Round 144 (Rated for Div. 2)D. Maximum Subarray

40 篇文章 0 订阅
14 篇文章 0 订阅

题目链接:

Problem - D - Codeforcesicon-default.png?t=N2N8https://codeforces.com/contest/1796/problem/D

 

题意:
选择k个不同位置+x,其他位置-x,求最大字段和

动态规划
我们设dp表示以i为结尾的最大字段和并且选择j个位置+x
那么我们可以分成三种情况

当 j = 0 时,即所有位置都不选,那么就是所有位置都减去x,根据常规的最大字段和dp即可,dp(i,j) = max(A[i] - x ,A[i]-x+dp(i-1,j))
接下来我们考虑取第i个位置的情况 ,那么如果前面i - 1结尾的字段和大于0那么取dp(i-1,j-1)一定是最优的,否则我们从0开始,可以得出 dp(i,j) = max(0,dp(i-1,j-1)) + A[i] +x
考虑不取第i个位置的情况,当前位置是需要 - x 的,那么dp(i,j) = max(0,dp(i-1,j)) + A[i] - x ,需要注意的是如果 i == j 时,此时是不合法的,因为当前不取的话,前i - 1个数字不可能选择 j个数

AC代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int a[N];
int dp[N][25];
void solve(){
	int n,k,x;
	cin>>n>>k>>x;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		for(int j=0;j<=k;j++){
			dp[i][j]=0;
		}
	}
	int ans=-0;
	for(int i=1;i<=n;i++){
		for(int j=max(k-n+i,0ll);j<=min(i,k);j++){
			if(j==0){
				dp[i][j]=max(a[i]-x,a[i]-x+dp[i-1][j]);
			}
			else {
				dp[i][j]=max(0ll,dp[i-1][j-1])+a[i]+x;
				if(j<i){
					dp[i][j]=max(max(0ll,dp[i-1][j])+a[i]-x,dp[i][j]);
				}
			}
			ans=max(ans,dp[i][j]);
		}
	}
	cout<<ans<<"\n";
}
signed main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int t=1;
	cin>>t;
	while(t--){
		solve();
	}
} 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值