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

题目链接:

Problem - D - Codeforcesicon-default.png?t=N2N8https://codeforces.com/contest/1796/problem/DEducational Codeforces Round 144 (Rated for Div. 2)D. Maximum Subarray_第1张图片

 

题意:
选择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
#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>t;
	while(t--){
		solve();
	}
} 


 

你可能感兴趣的:(DP,思维题,codefoeces,算法,动态规划)