码迷,mamicode.com
首页 > 其他好文 > 详细

100D Equal Cut

时间:2018-07-21 17:17:14      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:stack   target   const   暴力枚举   ret   位置   tco   end   cin   

传送门

分析

首先我们想到的肯定是n^3暴力枚举,但这显然不行。然后我们想到的就是二分了,但这题没有什么单调性,所以二分也不行。这时候我就想到了先枚举找出p2的位置再在它的左右两边找到p1和p3,但是良心的样例2告诉了我这样是不行的,因为让p2的位置最优并不意味着整体最优。之后我发现可以枚举p2,在这个基础上枚举p1和p3,因为如果之前p1或p3向右移了几位那它在之后一定不会向左移,这样我们有优化了一小点。根据这个思路我们不难再联想到如果p1+1的答案不如现在的p1优,那p1+2也一定不会更优,这个结论易证。所以我们便得到了一个O(n)做法。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define sp cout<<"---------------------------------------------------"<<endl
const long long inf=2e15+7;
long long pre[200010]; 
int main(){
      long long n,i,x,p1,p2,p3,minn,P;
      cin>>n;
      for(i=1;i<=n;i++){
          scanf("%lld",&x);
          pre[i]=pre[i-1]+x;
      }
      p1=1,p2=2,p3=3;
      long long ans=inf;
      for(p2;p2<n;p2++){
        minn=inf;
        for(i=p1;i<p2;i++)
          if(abs(pre[i]-(pre[p2]-pre[i]))<minn){
            minn=abs(pre[i]-(pre[p2]-pre[i]));
            p1=i;
          }else break;
        minn=inf;
        if(p3<=p2)p3=p2+1;
        for(i=p3;i<=n;i++)
          if(abs((pre[i]-pre[p2])-(pre[n]-pre[i]))<minn){
            minn=abs((pre[i]-pre[p2])-(pre[n]-pre[i]));
            p3=i;
          }else break;
        minn=inf;long long maxn=0;
        minn=min(pre[p1],min(pre[p2]-pre[p1],min(pre[p3]-pre[p2],pre[n]-pre[p3])));
        maxn=max(pre[p1],max(pre[p2]-pre[p1],max(pre[p3]-pre[p2],pre[n]-pre[p3])));
        ans=min(ans,maxn-minn);
      }
      cout<<ans<<endl;
      return 0;
}

100D Equal Cut

标签:stack   target   const   暴力枚举   ret   位置   tco   end   cin   

原文地址:https://www.cnblogs.com/yzxverygood/p/9346749.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!