UVALive 3177 長城守衛

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1178php

http://7xjob4.com1.z0.glb.clouddn.com/8e1ee1ef5ea10e46ebda75b88b058f47c++

 

題意:n我的圍圈,每人有不一樣或相同數量禮物,相鄰禮物不能同樣,求最少總禮物數。ide

思路: n是偶數:爲相鄰兩人禮物數和的最大值;n是奇數:二分法選禮物數量,看是否可行,設第一我的禮物爲前幾種,編號爲偶數的人儘可能在前面取,奇數的人儘可能在後面取,最後查看最後一人的禮物是否和第一我的的衝突。spa

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n;
 5 int r[100005],Left[100005],Right[100005];
 6 
 7 int check(int p)
 8 {
 9     int i,j;
10     int x=r[1],y=p-r[1];
11     Left[1]=x,Right[1]=0;
12     for(i=2;i<=n;i++)
13     {
14         if(i%2==0)
15         {
16             Left[i]=min(x-Left[i-1],r[i]);
17             Right[i]=r[i]-Left[i];
18         }
19         else
20         {
21             Right[i]=min(y-Right[i-1],r[i]);
22             Left[i]=r[i]-Right[i];
23         }
24     }
25     if(Left[n]==0)
26         return 1;
27     return 0;
28 }
29 
30 int main()
31 {
32     int i,j;
33     while(scanf("%d",&n)!=EOF && n!=0)
34     {
35         for(i=1;i<=n;i++)
36         {
37             scanf("%d",&r[i]);
38         }
39         if(n==1)
40         {
41             printf("%d\n",r[1]);
42             continue;
43         }
44 
45         int L=0,R=0;r[n+1]=r[1];
46         for(i=1;i<=n;i++)   L=max(L,r[i]+r[i+1]);
47         if(n%2==1)
48         {
49             for(i=1;i<=n;i++)   R=max(R,r[i]*3);
50             while(L<R)
51             {
52                 int mid=(L+R)/2;
53                 if(check(mid))
54                 {
55                     R=mid;
56                 }
57                 else
58                 {
59                     L=mid+1;
60                 }
61             }
62         }
63         printf("%d\n",L);
64     }
65     return 0;
66 }
View Code
相關文章
相關標籤/搜索