1.        题目

B_station

在离著名的国家Berland不远的地方,有一个水下工作站。这个工作站有N层。已知:是第i层装有Wi的水,最多可以容纳Li的水,恐怖分子炸毁第i层的代价是Pi。第i层一旦被炸毁,该层所有的水都将倾泻到第i+1层。如果某一层的水量超过了它的容量(即Li),那么该层就将自动被毁坏,所有的水也会倾泻到下一层。

Pivland的恐怖分子想要用最少的钱毁掉第N层,现在他雇佣你来计算,需要炸毁哪些层。

输入:第一行有一个自然数N(1<=n<=15000)。接下来的N行,每行3个整数Wi, Li, Pi(0<=Wi,Li,Pi<=15000)。

输出:输出需要炸毁的层的编号。

样例Input                    样例output

3                                  1

1000 1000 1                  2

0 1000 2

2 10 100

2.        题目实质

这个题讲的也很明白。

3.        算法

首先,不要一看见最优值就认为是动规,这个题找状态......

其实,他是一个枚举。

选择枚举对像:不妨设恐怖分子炸毁的最高层是第p层(第一层是最高层,第N层是最底层)。

因为恐怖分子的目标是毁灭第N层,所以水必须从第p层一直泻下去。如果存在一个i,满足Wp+Wp+1+…+Wi-1+Wi<=Li,也就是说前面几层的水全部泄下来也无法把第i层自动冲毁,那么就必须要使用***把它炸开了。

考察: Wp+Wp+1+…+Wi-1+Wi<=Li
这个式子要求一段的数字和,为了快速,用前缀和:
   令Si=W1+W2+…+Wi(特别的S0=0)。

上式可表示成: Si-Sp-1 <=Li

所以恐怖分子需要炸毁的层的集合就是Bomb[p]={p}∪{i |i>p Si-Sp-1<=Li}

我们枚举p,然后看哪些层需要炸毁。这样就得到了一个O(n2)的算法。

然后,这里主要讲一下优化:

剪枝:在你枚举的时候,在内层循环中记录一下当前炸了这么多层已经花了多少钱,当这个数目大于已经记录的最小值时, break 。(这样就能过)

记忆化:当搜到了一层的时候,已经可以自己冲垮而不用花钱,那么显然将炸的最高层再往上抬,它还是不用花钱,此时就需要将它记录下来,以后不用搜了。也可以在每次需要花钱的时候,记录下还有多少水就可以不用花钱了,到 0 的时候也就不用再搜了。

单调性优化:(大根堆、二分查找、单调队列 etc)

Bomb[p]={p}∪{i |i>p Si-Sp-1<=Li}  è

令Qi=Si-Li,那么:

Bomb[p]={p}∪{i |i>p Qi<=Sp-1}

注意到Sp是随着p的增加而递增的(单调性),观察两个集合:

Bomb[p]={p}∪{i |i>p Qi<=Sp-1}

Bomb[p-1]={p-1}∪{i |i>p-1 Qi<=Sp-2}

因为Sp-2<=Sp-1,所以{i |i>p-1 Qi<=Sp-2}包含于 Bomb[p],也就是说,Bomb[p-1]是在Bomb[p]的基础上,通过以下操作得到的:

删除所有的i∈Bomb[p],Qi>Sp-2。(所以找最大值,删除判断就行了)

添加p-1。

针对这两种操作,我们可以使用大根堆(Heap)(单调队列、二分查找什么的都行)。从大到小枚举p,对于每一个p,执行:

Step1. 如果堆的根i满足Qi >Sp-2,那么删除根;否则转Step3。

Step2. 转Step1。

Step3. 添加p-1。

每层至多进堆一次、出堆一次,所以总的时间复杂度是O(nlogn)。对于n<=15000的范围完全能够胜任了。

4.        注意事项

不要一看到最优值就写动规,也适当想一想基础算法。

注意观察数据范围,不要每次一上来就写最厉害(一般也是最难写)的优化,优化优化的不好就会变成退化了,像这个题,三个优化中有一个就可以 AC 。

5.        代码

只用了第一个优化,刚好能过(SueMiller)

var n:longint;

i,j,k:longint;

w,l,p:array[0..15001]of longint;

v,vv:array[0..15001]of boolean;

ans,temp,co:longint;

begin

assign(input,'station.in');reset(input);

assign(output,'station.out');rewrite(output);

fillchar(w,sizeof(w),0);

fillchar(l,sizeof(l),0);

fillchar(p,sizeof(p),0);

readln(n);

for i:=1 to n do

begin

readln(w[i],l[i],p[i]);

end;

if w[n]>l[n] then begin

writeln(0);

close(input);close(output);

halt;

end;

temp:=w[n];

k:=n;

while temp<=l[n] do

begin

dec(k);

temp:=temp+w[k];

end;

ans:=p[n];

fillchar(v,sizeof(v),false);

fillchar(vv,sizeof(vv),false);

vv[n]:=true;

for i:=k downto 1 do

begin

temp:=w[i];

if temp<=l[i] then

begin

co:=p[i];

v[i]:=true;

end;

for j:=i+1 to n do

begin

if temp+w[j]>l[j] then begin

temp:=temp+w[j];

continue

end

else begin

co:=co+p[j];

v[j]:=true;

temp:=temp+w[j];

if co>ans then begin

fillchar(v,sizeof(v),false);

break;

end;

end;

end;

if co<ans then

begin

vv:=v;

ans:=co;

fillchar(v,sizeof(v),false);

end;

end;

writeln(ans);

for i:=1 to n do

if vv[i] then write(i,' ');

writeln;

//  temp:=0;

//  for i:=1 to n do

//    if vv[i] then begin

//      temp:=temp+p[i];

//    end;

//  writeln(temp,'   ##');

close(input);close(output);

end.

大根堆 (Liukeke)

program liukeke;

var

w,p,l,s,q:array[0..15001] of longint;

f:array[0..15001] of longint;

ans:array[0..15001] of longint;

m,ans0,anscost,cost,i,n:longint;

procedure downsift(x:longint);

var

k,temp:longint;

begin

temp:=f[x];

k:=x<<1;

while k<=m do

begin

if(k<m)and(q[f[k]]<q[f[k+1]]) then inc(k);

if q[temp]<q[f[k]] then

begin

f[x]:=f[k];

x:=k;

k:=x<<1;

end

else break;

end;

f[x]:=temp;

end;

procedure upsift(x:longint);

var

k,temp:longint;

begin

temp:=f[x];

k:=x>>1;

while k>0 do

begin

if q[temp]>q[f[k]] then

begin

f[x]:=f[k];

x:=k;

k:=x>>1;

end

else break;

end;

f[x]:=temp;

end;

procedure sort(l,r:longint);

var

i,j,mid,temp:longint;

begin

i:=l;j:=r;mid:=ans[(l+r)>>1];

repeat

while ans[i]<mid do inc(i);

while ans[j]>mid do dec(j);

if i<=j then

begin

temp:=ans[i];

ans[i]:=ans[j];

ans[j]:=temp;

inc(i);

dec(j);

end;

until i>j;

if l<j then sort(l,j);

if i<r then sort(i,r);

end;

begin

assign(input,'station.in');reset(input);

assign(output,'station.out');rewrite(output);

readln(n);

for i:=1 to n do

readln(w[i],l[i],p[i]);

for i:=1 to n do

s[i]:=s[i-1]+w[i];

for i:=1 to n do

q[i]:=s[i]-l[i];

m:=1;

f[1]:=n;

cost:=p[n];

anscost:=p[n];

for i:=n downto 2 do

begin

//

while (q[f[1]]>s[i-2])and(m>0) do

begin

dec(cost,p[f[1]]);

f[1]:=f[m];

dec(m);

downsift(1);

end;

//

inc(m);

f[m]:=i-1;

upsift(m);

//

inc(cost,p[i-1]);

if cost<anscost then

begin

anscost:=cost;

ans:=f;

ans0:=m;

end;

end;

//outit;

sort(1,ans0);

writeln(anscost);

for i:=1 to ans0 do

write(ans[i],' ');

close(input);

close(output);

end.

转载于:https://www.cnblogs.com/SueMiller/archive/2011/10/11/2207761.html

解题报告 B_station相关推荐

  1. uscao 线段树成段更新操作及Lazy思想(POJ3468解题报告)

    线段树成段更新操作及Lazy思想(POJ3468解题报告) 标签: treequerybuildn2cstruct 2011-11-03 20:37 5756人阅读 评论(0) 收藏 举报  分类: ...

  2. 解题报告(十八)数论题目泛做(Codeforces 难度:2000 ~ 3000 + )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  3. 【解题报告系列】超高质量题单 + 题解(ACM / OI)超高质量题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我新写的超高质量的题解和代码,题目难度不 ...

  4. 解题报告(三)多项式求值与插值(拉格朗日插值)(ACM / OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  5. 解题报告(十三)中国剩余定理(ACM / OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  6. 解题报告(四)生成函数(ACM/ OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  7. 解题报告(八) prufer 序列与 Cayley 公式(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  8. 解题报告(一)E、(BZOJ4589)Hard Nim(博弈论 + FWT)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  9. 解题报告(五)组合计数(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

最新文章

  1. AcornCharts
  2. 5G NGC — 关键技术 — R15 SBA
  3. java.lang包—StringBuffer类和StringBuilder类
  4. Windows系统程序设计之结构化异常处理
  5. Java基础知识——Java数组详解
  6. runloop - 面试题
  7. C#LeetCode刷题之#824-山羊拉丁文​​​​​​​(Goat Latin)
  8. php数组连起来,PHP 数组的拼接重组
  9. 关系数据库第一第二第三范式
  10. 大牛总结的 Git 使用技巧,写得太好了!
  11. EDA技术实用教程 | 复习六 | 过程语句always
  12. 21天学通mysql_《21天学通JavaWeb》 - 随笔分类 - 疯狂delphi - 博客园
  13. 使用Netsparker扫描及**某站点
  14. Linux - ZModem协议的sz命令传输文件异常
  15. Mac上qmc0文件转码为mp3
  16. 笔记本输字母p出现仅计算机,电脑打不了字只有字母怎么办?最简单的解决方法...
  17. 用于实时视频和图像去雾的优化对比度增强算法
  18. 为什么90%的人物画像都是没用的?
  19. unity 控制对象移动、旋转
  20. POM 文件中 licenses 许可证的定义

热门文章

  1. 蓝桥杯 BEGIN-2 入门训练 序列求和
  2. LeetCode 515. Find Largest Value in Each Tree Row
  3. perl调用shell命令并获取输出
  4. zookeeper安装与测试
  5. Javascript获取select下拉框选中的的值
  6. Java 里面 final 与 static
  7. Android Jni开发,报com.android.ide.common.process.ProcessException: Error configuring 错误解决方案...
  8. Java各层之间的关系
  9. BZOJ1433[ZJOI2009]假期的宿舍——二分图最大匹配
  10. Atitit 外包管理规范attilax总结