NC20467. [ZJOI2006]TROUBLE 皇帝的烦恼
描述
输入描述
第一行有一个整数n(1<=n<=20000)。
接下来n行每行一个整数ai,表示第i个将军要求得到多少种勋章。(1<=ai<=100000)
输出描述
输出一个整数,即最少需要多少种勋章。
示例1
输入:
4 2 2 1 1
输出:
4
C++11(clang++ 3.9) 解法, 执行用时: 6ms, 内存消耗: 620K, 提交时间: 2020-02-15 17:50:53
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1;ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } #define MAXN 20010 int N,a[MAXN],L,R,f[MAXN],g[MAXN]; bool check(int x) { f[1]=g[1]=a[1]; for(int i=2;i<=N;i++) f[i]=max(0,a[i]-x-g[i-1]+a[1]+a[i-1]),g[i]=min(a[1]-f[i-1],a[i]); return f[N]==0; } int main() { N=read(); int maxx=0; for(int i=1;i<=N;i++) a[i]=read();a[N+1]=a[1]; for(int i=1;i<=N;i++) maxx=max(maxx,a[i]+a[i+1]); int L=maxx,R=maxx*2; while(L<=R) { int mid=(L+R)>>1; if(check(mid)) R=mid-1;else L=mid+1; } printf("%d\n",L); return 0; }