#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(双指针&差分)的主要内容,如果未能解决你的问题,请参考以下文章