省选专练ZJOI2006皇帝的烦恼

来源:互联网 发布:网络写手大神 编辑:程序博客网 时间:2024/04/19 21:02

这题可以蜜汁骗分

直接输出两边之和最大值——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;}