迷宫大门
(File IO): input:door.in output:door.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
题目描述
在跳棋游戏大获全胜后,小明就开始一个人在校园里溜达了。突然他在校园角落里发现了一面神奇的墙壁,墙壁上有一排钉子,每个钉子上都挂着一根两端系有小球的绳子,如下图所示
小明可以调整每一根绳子在钉子左右两端的长度,当来自不同绳子的相邻小球高度一样时(具体可见样例说明),便可获得积分1分。当小明的方案获得最高积分时,迷宫大门就会开启,小明就可以进去寻找宝藏啦!
输入
输入文件door.in第一行为一个正整数n,表示墙上的绳子数。
接下来n行,每行2个整数a和b,表示绳子左右两端的初始长度。
输出
输出文件door.out仅有一个正整数,表示小明可以获得的最高积分。
样例输入
3
1 1
3 2
1 4
样例输出
2
数据范围限制
提示
正解
考试时就想到了,但就是打不出来!!!!!
首先,我们想一下怎么确定是否对于这段绳子首尾相接有解。(可能这段话很令人费解)
我们可以用不等式。
对!先弄一个范围(不等式都有范围),就是说L一定<=可行的解,并一定<=R。如果L>R,明显,无解。
是的。可以列不等式。设在第一个绳子的左边长度为x,由于每一根绳子的长度时固定的,所以右边绳子长度也可以求出来。由于要首尾长度一样,这样就可以一直列方程。直到结尾。不等式的形式均为:ax+b>=0.(a=1或-1).对a与b的取值情况进行分类讨论。将取值的范围不断的缩小。
然后呢?
贪心!
为什么呢?
我们要明白一个性质(黑暗森林性质):如果L~R是极限,那么L~P(P>R)都是不可行的。为什么呢?很容易,应为新的长度是只能约束你的L.R值的,而不能给他们扩大范围。
这样:
0000000000
如果1~8是极限,9~10是极限。
可我们选择的是1~6,7~10是绝对不可能的。那么值就不是最优的了。
所以,我们选择的应该是从1开始的向后选一段最长有解的首尾相连的绳子。在隔一个位置在向后选一段,直到选完为止。这样的解就是最优解。
代码
var
n,o,u,ans,now,xi,l,r,fu:int64;
i:longint;
a:array[0..500000] of int64;
begin
assign(input,'door.in');
assign(output,'door.out');
reset(input);
rewrite(output);
read(n);
for i:=1 to n do
begin
read(o,u);
a[i]:=o+u;
end;
ans:=0;
now:=1;
a[n+1]:=maxlongint;
while (now<=n) do
begin
l:=0;
r:=9223372036854775807;
fu:=1;
xi:=0;
while (l<=r) and (now<=n+1) do
begin
fu:=-fu;
xi:=a[now]-xi;
if fu<0 then
begin
if r>xi then
r:=xi;
end
else
begin
if l<-(xi) then
l:=-(xi);
end;
inc(now);
end;
inc(ans);
dec(now);
end;
writeln(n-ans);
close(input);
close(output);
end.