#3468. 「JOI 2021 Final」有趣的家庭菜园 4(双指针&差分)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#3468. 「JOI 2021 Final」有趣的家庭菜园 4(双指针&差分)相关的知识,希望对你有一定的参考价值。

#3468. 「JOI 2021 Final」有趣的家庭菜园 4(双指针&差分)

1.双指针,差分一下后,维护两个指针,每次贪心的修改即可。

code

// Problem: #3468. 「JOI 2021 Final」有趣的家庭菜园 4
// Contest: LibreOJ
// URL: https://loj.ac/p/3468
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Date: 2021-07-09 09:12:50
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
int a[N],n;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=n;i;i--) a[i]-=a[i-1];
	ll ans=0;
	for(int l=1,r=n;l<r;){
		while(a[l]>0&&l<r) l++; 
		while(a[r]<0&&l<r) r--;
		if(l==r){
			if(!a[l]) ans++;
			break;
		}
		if(l<r){
			int x=abs(a[l]);
			int y=a[r];
			if(x<y){
				ans+=x+1;
				a[l]=1;
				a[r]-=(x+1);
				l++;
			}
			else {
				ans+=y+1;
				a[r]=-1;
				a[l]+=(y+1);
				r--;
			}
		}
	}
	printf("%lld\\n",ans);
	return 0;
}

2.差分+前缀和+后缀和,然后枚举 k k k m i n min min即可。

code

// Problem: #3468. 「JOI 2021 Final」有趣的家庭菜园 4
// Contest: LibreOJ
// URL: https://loj.ac/p/3468
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Date: 2021-07-09 09:12:50
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define IOS ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
int a[N],n;
ll pre[N],suf[N];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=2;i<=n;i++){
		pre[i]=pre[i-1]+max(0,a[i-1]-a[i]+1);
	}
	for(int i=n-1;i;i--){
		suf[i]=suf[i+1]+max(0,a[i+1]-a[i]+1);
	}
	ll ans=1e18;
	for(int i=1;i<=n;i++) ans=min(ans,max(suf[i],pre[i]));
	printf("%lld\\n",ans);
	return 0;
}

以上是关于#3468. 「JOI 2021 Final」有趣的家庭菜园 4(双指针&差分)的主要内容,如果未能解决你的问题,请参考以下文章

年轮蛋糕JOI2014Final

[JOI 2015 Final]分蛋糕 2

2018.10.1「JOI 2014 Final」年轮蛋糕

JOI 2020 Final 火灾

[JOI 2014 Final]IOI 馒头

2018.9.20JOI 2017 Final T2「準急電車 / Semiexpress」