uva1335(贪心)
2015-01-30 15:25
246 查看
题意:
又是看了题解,感觉最近做题都没什么想法出来:
有n个人围成一个圈,其中第i个人想要ri个不同的礼物。相邻的两个人可以聊天,炫耀自己的礼物。如果两个相邻的人拥有同一种礼物,则双方都会很不高兴。问:一共需要多少种礼物才能满足所有人的需要?假设每种礼物有无穷多个,不相邻的两个人不会一起聊天,所以即使拿到相同的礼物也没关系。
比如,一共有5个人,每个人都要一个礼物,则至少要3种礼物。如果把这3种礼物编号为1, 2, 3,则5个人拿到的礼物应分别是:1,2,1,2,3。如果每个人要两个礼物,则至少要5种礼物,且5个人拿到的礼物集合应该是:{1,2},{3,4},{1,5},{2,3},{4,5}。
思路:
如果n为偶数,那么答案为相邻的两个人的r值之和的最大值,即p=max{ri+ri+1}(i=1, 2, …, n),规定rn+1=r1。不难看出,这个数值是答案的下限,而且还可以构造出只用p种礼物的方案:对于一个编号为i的人,如果i为奇数,发编号为1~r的礼物ri;如果i为偶数,发礼物p-ri+1~p,请读者自己验证它是否符合要求。
n为奇数的情况比较棘手,因为上述方法不再奏效。这个时候需要二分答案:假设已知共有p种礼物,该如何分配呢?设第1个人的礼物是1~r1,不难发现最优的分配策略一定是这样的:编号为偶数的人尽量往前取,编号为奇数的人尽量往后取。这样,编号为n的人在不冲突的前提下,尽可能地往后取了rn样东西,最后判定编号为1的人和编号为n的人是否冲突即可。比如,n = 5,A = {2, 2, 5, 2, 5},p = 8时,则第1个人取{1, 2}, 第2个人取{3, 4}, 第3个人取{8, 7, 6, 5, 2}, 第4个人取{1,
3}, 第5个人取{8, 7, 6, 5, 4},由于第1个人与第5个人不冲突,所以p = 8是可行的。
程序实现上,由于题目并不要求输出方案,因此,只需记录每个人在[1~r1]的范围内取了几个,在[r1+1~n]的范围里取了几个(在程序中分别用left[i]和right[i]表示),最后判断出第n个人在[1~r1]里面是否有取东西即可。
又是看了题解,感觉最近做题都没什么想法出来:
有n个人围成一个圈,其中第i个人想要ri个不同的礼物。相邻的两个人可以聊天,炫耀自己的礼物。如果两个相邻的人拥有同一种礼物,则双方都会很不高兴。问:一共需要多少种礼物才能满足所有人的需要?假设每种礼物有无穷多个,不相邻的两个人不会一起聊天,所以即使拿到相同的礼物也没关系。
比如,一共有5个人,每个人都要一个礼物,则至少要3种礼物。如果把这3种礼物编号为1, 2, 3,则5个人拿到的礼物应分别是:1,2,1,2,3。如果每个人要两个礼物,则至少要5种礼物,且5个人拿到的礼物集合应该是:{1,2},{3,4},{1,5},{2,3},{4,5}。
思路:
如果n为偶数,那么答案为相邻的两个人的r值之和的最大值,即p=max{ri+ri+1}(i=1, 2, …, n),规定rn+1=r1。不难看出,这个数值是答案的下限,而且还可以构造出只用p种礼物的方案:对于一个编号为i的人,如果i为奇数,发编号为1~r的礼物ri;如果i为偶数,发礼物p-ri+1~p,请读者自己验证它是否符合要求。
n为奇数的情况比较棘手,因为上述方法不再奏效。这个时候需要二分答案:假设已知共有p种礼物,该如何分配呢?设第1个人的礼物是1~r1,不难发现最优的分配策略一定是这样的:编号为偶数的人尽量往前取,编号为奇数的人尽量往后取。这样,编号为n的人在不冲突的前提下,尽可能地往后取了rn样东西,最后判定编号为1的人和编号为n的人是否冲突即可。比如,n = 5,A = {2, 2, 5, 2, 5},p = 8时,则第1个人取{1, 2}, 第2个人取{3, 4}, 第3个人取{8, 7, 6, 5, 2}, 第4个人取{1,
3}, 第5个人取{8, 7, 6, 5, 4},由于第1个人与第5个人不冲突,所以p = 8是可行的。
程序实现上,由于题目并不要求输出方案,因此,只需记录每个人在[1~r1]的范围内取了几个,在[r1+1~n]的范围里取了几个(在程序中分别用left[i]和right[i]表示),最后判断出第n个人在[1~r1]里面是否有取东西即可。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N =100005; int n, ans, l, r; int gift ; int left ; int right ; bool judge(int total) { int x = gift[0]; int y = total - gift[0]; left[0] = gift[0]; right[0] = 0; for(int i = 1 ; i < n ;i++) { if(i % 2 == 0) { right[i] = min(y - right[i - 1] , gift[i]); left[i] = gift[i] - right[i]; } else { left[i] = min(x - left[i - 1] , gift[i]); right[i] = gift[i] - left[i]; } } return left[n - 1] == 0; } int main () { while(scanf("%d",&n)!= EOF && n) { for(int i = 0 ;i < n ; i++) { scanf("%d",&gift[i]); } ans = 0; for(int i = 0 ; i < n - 1;i++) { ans = max(ans , gift[i] + gift[i + 1]); } ans = max(ans , gift[0] + gift[n - 1]); if(n % 2 == 0) printf("%d\n",ans); else if(n == 1) printf("%d\n",gift[0]); else { l = ans; r = ans * 3; int mid; while(r > l) { mid = (l + r) / 2; if(judge(mid)) { r = mid; } else l = mid + 1; } printf("%d\n",l); } } }
相关文章推荐
- UVALive 3177 && uva 1335 Beijing Guards (贪心+二分)
- CERC 2004 / UVa 1335 Beijing Guards (二分&贪心&想法题)
- UVa 1335 Beijing Guards (二分+贪心)
- UVA 1335 - Beijing Guards(贪心)
- UVA 1335 Beijing Guards 二分贪心
- UVA 1335 Beijing Guards 二分贪心
- 【二分答案+贪心】UVa 1335 - Beijing Guards
- 二分+贪心-uva-1335 - Beijing Guards
- UVA12130 Summits(BFS + 贪心)
- uvalive5986(贪心)
- UVa 10905 Children's Game (贪心)
- uva 1316 - Supermarket(贪心)
- UVALive 4225 / HDU 2964 Prime Bases 贪心
- UVA 1379 - Pitcher Rotation(DP + 贪心)
- UVA1153-Keep the Customer Satisfied(贪心+优先队列)
- 例题1.16 长城守卫 UVa1335
- uva 10905 - Children's Game(排序中的贪心)
- UVaLive 7454 Parentheses (水题,贪心)
- UVALive - 2757 Supermarket 贪心+优先队列
- uva 1346 - Songs(贪心)