Beijing was once surrounded by four rings of city walls: the Forbidden City Wall, the Imperial City Wall, the Inner City Wall, and finally the Outer City Wall. Most of these walls were demolished in the 50s and 60s to make way for roads. The walls were protected by guard towers, and there was a guard living in each tower. The wall can be considered to be a large ring, where every guard tower has exaetly two neighbors.

The guard had to keep an eye on his section of the wall all day, so he had to stay in the tower. This is a very boring job, thus it is important to keep the guards motivated. The best way to motivate a guard is to give him lots of awards. There are several different types of awards that can be given: the Distinguished Service Award, the Nicest Uniform Award, the Master Guard Award, the Superior Eyesight Award, etc. The Central Department of City Guards determined how many awards have to be given to each of the guards. An award can be given to more than one guard. However, you have to pay attention to one thing: you should not give the same award to two neighbors, since a guard cannot be proud of his award if his neighbor already has this award. The task is to write a program that determines how many different types of awards are required to keep all the guards motivated.

Input

The input contains several blocks of test eases. Each case begins with a line containing a single integer ln100000, the number of guard towers. The next n lines correspond to the n guards: each line contains an integer, the number of awards the guard requires. Each guard requires at least 1, and at most l00000 awards. Guard i and i + 1 are neighbors, they cannot receive the same award. The first guard and the last guard are also neighbors.

The input is terminated by a block with n = 0.

Output

For each test case, you have to output a line containing a single integer, the minimum number x of award types that allows us to motivate the guards. That is, if we have x types of awards, then we can give as many awards to each guard as he requires, and we can do it in such a way that the same type of award is not given to neighboring guards. A guard can receive only one award from each type.

Sample Input

3
4
2
2
5
2
2
2
2
2
5
1
1
1
1
1
0

Sample Output

8
5
3

题意: 有n个人, 每人都需要wi种礼物, 但是相邻的人得礼物是不可以相同的, 现在要你求出最少的礼物数满足全部人的需求, 每种礼物的数量是无限的.

解题思路:

1. 当n为偶数时, 答案是相邻两人之间的的w值最大和, 即p = max{ p, wi + wi+1 }.并且可以看出,此p为礼物数的下限。

2. 当n为奇数时, 采用二分答案求解, 左边界为相邻两人之间wi值最大和(注意奇数情况时,第1人和第n人会导致冲突),右边界为所有人的wi值之和;假设p种礼物是否满足分配:

假设: 第一个人得到礼物1~r1, 分配的贪心策略可以是: 偶数编号的人尽量往前取, 奇数的人尽量往后取. 这样需要第n个人在不冲突的条件下, 尽量可能的往后取wn样礼物. 最后判断编号1和编号n的人是否冲突即可.

例: p = 8, r = {2,2,5,2,5}

第一人:{1,2}, 第二人:{3,4}, 第三人:{8,7,6,5,2}, 第四人:{1,3}, 第五人:{8,7,6,5,4}

 bool ok(int m)
{
Left[] = w[]; Right[] = ;
for(int i = ; i < n; i++)
{
if(i%)
{
if(w[]-Left[i-]-w[i] >= )
{
Left[i] = w[i];
Right[i] = ;
}
else
{
Left[i] = w[]-Left[i-];
Right[i] = w[i]-Left[i];
}
}
else
{
if(m-w[]-Right[i-]-w[i] >= )
{
Left[i] = ;
Right[i] = w[i];
}
else
{
Right[i] = m-w[]-Right[i-];
Left[i] = w[i]-Right[i];
}
}
}
return Left[n-] == ;
}

如家大神的比自己的简单诶。自己以后得学会简化算法:

bool ok(int m)
{
Left[] = w[]; Right[] = ;
for(int i = ; i < n; i++)
{
if(i%)
{
Left[i] = min(w[]-Left[i-], w[i]);
Right[i] = w[i] - Left[i];
}
else
{
Right[i] = min(m-w[]-Right[i-], w[i]);
Left[i] = w[i]-Right[i];
}
}
return Left[n-] == ;
}

附代码:

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring> using namespace std;
const int maxn = ;
int n, ans;
int w[maxn];
int Left[maxn], Right[maxn]; bool ok(int m)
{
Left[] = w[]; Right[] = ;
for(int i = ; i < n; i++)
{
if(i%)
{
Left[i] = min(w[]-Left[i-], w[i]);
Right[i] = w[i] - Left[i];
}
else
{
Right[i] = min(m-w[]-Right[i-], w[i]);
Left[i] = w[i]-Right[i];
}
}
return Left[n-] == ;
} int main()
{
while(scanf("%d", &n) && n)
{
ans = ;
for(int i = ; i < n; i++)
scanf("%d", &w[i]);
if(n == ) {printf("%d\n", w[]); continue;}
w[n] = w[];
int L = , R = ;
for(int i = ; i < n; i++)
{
L = max(L, w[i]+w[i+]);
R += w[i];
}
if(n%)
{
while(L < R)
{
int M = L + (R-L)/;
if(ok(M)) R = M;
else L = M+;
}
}
printf("%d\n", L);
}
return ;
}

【二分答案+贪心】UVa 1335 - Beijing Guards的更多相关文章

  1. uva 1335 - Beijing Guards(二分)

    题目链接:uva 1335 - Beijing Guards 题目大意:有n个人为成一个圈,其中第i个人想要r[i]种不同的礼物,相邻的两个人可以聊天,炫耀自己的礼物.如果两个相邻的人拥有同一种礼物, ...

  2. UVa 1335 Beijing Guards (二分+贪心)

    题意:n 个人成一个圈,每个人想要 ri 种不同的礼物,要求相邻两个人没有相同的,求最少需要多少礼物. 析:如果 n 是偶数,那么答案一定是相邻两个人的礼物总种数之和的最大值,那么如果是奇数,就没那么 ...

  3. UVA 1335 Beijing Guards(二分答案)

    入口: https://cn.vjudge.net/problem/UVA-1335 [题意] 有n个人为成一个圈,其中第i个人想要r[i]种不同的礼物,相邻的两个人可以聊天,炫耀自己的礼物.如果两个 ...

  4. uva 1335 - Beijing Guards

    竟然用二分,真是想不到: 偶数的情况很容易想到:不过奇数的就难了: 奇数的情况下,一个从后向前拿,一个从前向后拿的分配方法实在太妙了! 注: 白书上的代码有一点点错误 代码: #include< ...

  5. BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心

    BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心 Description Bessie烘焙了一块巧克力蛋糕.这块蛋糕是由R*C(1 <= R,C ...

  6. 洛谷3933 Chtholly Nota Seniorious 二分答案+贪心

    题目链接 题意 给你一个N*M的矩阵 (N,M <=2000)  把他分成两部分 使两部分的极差较大的一个最小  求这个最小值.然后分矩阵的要求是:每个部分内部的方块之间,可以通过上下左右相互到 ...

  7. 【二分答案+贪心】解决“最小值最大”问题(UVa 12124 - Assemble)

    Problem A - Assemble Time limit: 2 seconds Recently your team noticed that the computer you use to p ...

  8. 【洛谷】【二分答案+贪心】P1316 丢瓶盖

    [题目描述:] 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? [ ...

  9. BZOJ5321 JXOI2017加法(二分答案+贪心+堆+树状数组)

    二分答案后得到每个位置需要被加的次数.考虑贪心.从左到右考虑每个位置,将以该位置为左端点的区间按右端点从大到小加进堆.看该位置还需要被加多少次,如果不需要加了就不管,否则取堆顶区间将其选择,BIT实现 ...

随机推荐

  1. HTTP DNS小结

    https://www.dnspod.cn/httpdns/guide HttpDNS是使用HTTP协议向DNS服务器的80端口进行请求,代替传统的DNS协议向DNS服务器的53端口进行请求,绕开了运 ...

  2. Android Studio 模拟器启动问题——黑屏 死机 解决方法

    今天用了下Android Studio,出现了一些问题,现在将启动过程中遇到的问题和解决方案列出来,方便大家参考. 安装过程不多说,网上一搜一大把. 那直接说问题吧: 1. 无法启动,报错:Faile ...

  3. sublime text2注册码

    ----- BEGIN LICENSE ----- Andrew Weber Single User License EA7E-855605 813A03DD 5E4AD9E6 6C0EEB94 BC ...

  4. JavaScript获取HTML页面源代码

    来自:http://www.cnblogs.com/luckbird/archive/2008/02/01/1061048.html <a href="javascript:gets( ...

  5. python 继承和多态

    在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base class.Supe ...

  6. android 随手记 videoview循环播放网络视频 和mediaplayer+sufaceview播放网络视频

    1:videoview循环播放视频 1>xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res ...

  7. UI进阶 多线程

    一.多线程概述 程序.进程.线程 程序:由源代码生成的可执行应用.(例如:QQ.app) 进程:一个正在运行的程序可以看做一个进程.(例如:正在运行的QQ就是一个进程),进程拥有独立运行所需的全部资源 ...

  8. ios开发 数据库版本迁移手动更新迭代和自动更新迭代

    数据库版本迁移顾名思义就是在原有的数据库中更新数据库,数据库中的数据保持不变对表的增.删.该.查. 数据持久化存储: plist文件(属性列表) preference(偏好设置) NSKeyedArc ...

  9. ASP.NET线程与异步

    什么是线程? 线程简单来说就是一种数据结构,用来管理这个程序的执行状态,其中包括 1.线程核心对象->寄存器的状态 2.线程环境块,是一块用户模式下的内存,包含线程的异常处理链的头部.线程的局部 ...

  10. Asp.Net事务和异常处理:

    Asp.Net事务和异常处理: 一.什么是事务处理? 事务处理是一组组和成逻辑工作单元的数据库操作,虽然系统中可能会出错,但事务将控制和维护每个数据库的一致性和完整性. 如果在事务过程中没有遇到错误, ...