UVALive 3177 长城守卫
Posted cyd2014
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVALive 3177 长城守卫相关的知识,希望对你有一定的参考价值。
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1178
http://7xjob4.com1.z0.glb.clouddn.com/8e1ee1ef5ea10e46ebda75b88b058f47
题意:n个人围圈,每人有不同或相同数量礼物,相邻礼物不能一样,求最少总礼物数。
思路: n是偶数:为相邻两人礼物数和的最大值;n是奇数:二分法选礼物数量,看是否可行,设第一个人礼物为前几种,编号为偶数的人尽量在前面取,奇数的人尽量在后面取,最后查看最后一人的礼物是否和第一个人的冲突。
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 }
以上是关于UVALive 3177 长城守卫的主要内容,如果未能解决你的问题,请参考以下文章
Uva 长城守卫——1335 - Beijing Guards
2021-12-17:长城守卫军问题。 长城上有连成一排的n个烽火台,每个烽火台都有士兵驻守。 第i个烽火台驻守着ai个士兵,相邻峰火台的距离为1。另外,有m位将军, 每位将军可以驻守一个峰火台,每个