Beijing Guards

来源:互联网 发布:网络协议栈是什么 编辑:程序博客网 时间:2024/05/29 17:31

题意:

有n个人围成一个圈,给第i个ri个礼物,且相邻的人礼物不重,求最少礼物种类

思路:

如果n为偶数,那么最大值是相邻的两值相加的最大

如果n为奇数,那么用二分法确定最小值,判断原则:

将资源分为左边和右边两堆

首先左边分配t[0]个,也就是t[0]全部左取,然后奇数号取左,不足的右补(m-t[0]),偶数号右取,这样第n个人取得是右边,如果右边剩余不足左取的话,那就是不行的,即f[n-1]!=0则不行

ps : 补博好累

#include<cstdio>#include<iostream>#include<cstring>#include<string>using namespace std;int n, ans;int t[100010];int Left[100010], Right[100010];bool ok(int m){    Left[0] = t[0]; Right[0] = 0;    for(int i = 1; i < n; i++)    {        if(i%2)        {            Left[i] = min(t[0]-Left[i-1], t[i]);            Right[i] = t[i] - Left[i];        }        else        {            Right[i] = min(m-t[0]-Right[i-1], t[i]);            Left[i] = t[i]-Right[i];        }    }    return Left[n-1] == 0;}  int main() {     while(scanf("%d", &n) && n)     {         ans = 0;         for(int i = 0; i < n; i++)             scanf("%d", &t[i]);         if(n == 1) {printf("%d\n", t[0]); continue;}         t[n] = t[0];         int l = 0, r = 0;         for(int i = 0; i < n; i++)         {             l = max(l, t[i]+t[i+1]);             r += t[i];         }      if(n%2)        {             while(l < r)             {                 int M = l + (r-l)/2;                 if(ok(M)) r = M;                 else l = M+1;             }         }  printf("%d\n", l);     }return 0;}


0 0
原创粉丝点击