D. Beautiful Array 贪心或dp

题目链接:https://cn.vjudge.net/problem/CodeForces-1155D

题意:n个数,可以选择某个区间的数乘x,也可以不选,求区间和的最大值。

题解1:贪心,通过分析我们可以得到乘x的那个区间我们肯定取到了,那么我们就取一个区间[l, r]乘x,这种情况下,要想使结果尽可能大,那么再加上从l-1往前取个最大连续和L[l-1],从r+1往回后取个最大连续和R[r+1]即可,得到(sum[r]-sum[l-1])*x+L[l-1]+R[r+1],化简得到,sum[r]*x  + R[r+1]  - (sum[l-1]*x - L[l-1]),因此我们枚举r,维护(sum[l-1]*x - L[l-1])最小即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
int n,x;
int a[N];
ll l[N],r[N],sum[N];
int main()
{
	scanf("%d%d",&n,&x);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		sum[i]=sum[i-1]+a[i];
		l[i]=max(l[i-1]+a[i],0LL);
	}
	for(int i=n;i>=1;i--)
		r[i]=max(r[i+1]+a[i],0LL);
	ll ans=0,minn=0;
	for(int i=1;i<=n;i++)
	{
		ans=max(ans,r[i]+sum[i-1]*x-minn);
		minn=min(minn,sum[i]*x-l[i]);
	}
	ans=max(ans,sum[n]*x-minn);
	printf("%lld\n",ans);
	return 0;	
} 

题解2:dp[i][0]  表示到第i位置这个数不乘x,并且前面也没有乘过x;dp[i][1]表示到第i位置不乘x,前面乘过x了;dp[i][3]表示到i乘x;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
int n,x,a[N];
ll dp[N][3];
int main()
{
	scanf("%d%d",&n,&x);
	ll ans=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		dp[i][0]=max(dp[i-1][0],0LL)+a[i];  
		dp[i][1]=max(max(dp[i-1][0],dp[i-1][1]),max(dp[i-1][2],0LL))+a[i];
		dp[i][2]=max(max(dp[i-1][0],dp[i-1][2]),0LL)+(ll)a[i]*x;
		ans=max(max(dp[i][0],dp[i][1]),max(dp[i][2],ans));
	}
	printf("%lld\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/89468964