F-小苯的线性dp

题目链接:https://ac.nowcoder.com/acm/contest/104637/F

题意:

分别对k次操作(0<=k<n)的数组求出其极差的最大值
(每次操作可以合并两个相邻元素)

思路:

显然题目数据范围允许N方做法

发现要让极差变大,只能将最大值变大

因此对于每一个k次操作求得的数组,我们可以枚举钦定一个元素作为其最小值

那么最大值即 其前缀数组 和 后缀数组中 长度范围不超过k+1 的子数组的元素之和

这是本题的关键

每次对ans取max即可

由于默认有前缀 和 后缀,因此当k=n-2时,即数组被划分为了两个区间,此时需要特判

void solve(){
	int n;cin>>n;
	vector<int>a(n+1);
	vector<int>sum(n+1);
	for(int i=1;i<=n;i++){
		cin>>a[i];sum[i]=sum[i-1]+a[i];
	}
	for(int k=1;k<=n-2;k++){
		vector<int>pre(n+2,0);
		vector<int>suf(n+2,0);
		for(int i=1;i<=n;i++){
			pre[i]=max(pre[i-1],sum[i]-sum[max(0,i-k)]);
		}
		for(int i=n;i>=1;i--){
			suf[i]=max(suf[i+1],sum[min(n,i+k-1)]-sum[i-1]);
		}
		int ans=0;
		for(int i=1;i<=n;i++){
			ans=max(ans,max(pre[i-1]-a[i],suf[i+1]-a[i]));
		}
		cout<<ans<<' ';
	}
	cout<<max(sum[n]-sum[1]-a[1],sum[n-1]-a[n])<<' '<<0<<endl;
}
posted @ 2025-03-26 17:07  Marinaco  阅读(20)  评论(0)    收藏  举报
//雪花飘落效果