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 }