这题可以蜜汁骗分
直接输出两边之和最大值——60,对于省选还是不错的。
答案绝对保证单调。
于是考虑二分。
check不好写。
用dp判。
看代码吧
#include<bits/stdc++.h>
using namespace std;
int a[30001]={0};
int maxsum[30001]={0};
int minsum[30001]={0};
int n;
void init(){
memset(maxsum,0,sizeof(maxsum));
memset(minsum,0,sizeof(minsum));
}
int mx[100010],mn[100010];
bool check(int x){
mx[1]=mn[1]=a[1];
for(int i=2;i<=n;i++){
mx[i]=min(a[1]-mn[i-1],a[i]);
mn[i]=max(a[1]+a[i]+a[i-1]-mx[i-1]-x,0);
}
if (mn[n]==0) return true; else return false;
}
//int check(int x){
init();
// minsum[1]=a[1];
// maxsum[1]=a[1];
// for(int i=2;i<=n;i++){
// maxsum[i]=min(a[1]-minsum[i-1],a[i]);
// minsum[i]=max(a[1]+a[i]+a[i-1]-maxsum[i-1]-x,0);
// }
// if(minsum[n]==0){
// return 1;
// }
// else{
// return -1;
// }
//}
int main(){
scanf("%d",&n);
int l=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
l=max(a[i]+a[i-1],l);
}
int r=50000000;
int ans;
// cout<<check(3)<<endl;
while(l<=r){
int mid=(l+r)/2;
// cout<<mid<<endl;
if(check(mid)==1){
ans=mid;
r=mid-1;
}
else{
l=mid+1;
}
}
cout<<ans;
}