tyvj p1313(烽火传递)(80=>100分)

假如不看数据的话,是一道很简单的动态规划的题目。

很容易想到方程:f[i]:=min(f[i],f[i-j]+s[i]);(1<=j<=m);这个是 O(mn)的算法

但是一看数据- - 一百万。

优化有两种方法,一种是用堆O(nlogn), 一种使用单调队列优化O(n)。

每次更新单调队列时,后面比当前状态f[i]大的全部踢走,然后把它加入队尾,同时把不能继续使用的值(序号小于当前序号减去m的值)踢走,保证了队列的单调递增性。

我们就有 f[i]:=s[i]+f[d[t]](t是队列的头指针,d储存队列的数组)。然后把f[i]加入到队列之中。

代码:

 1 program p1313;
 2 var
 3         i,j,k,l,m,n,ans,t,w:longint;
 4         f,s,d:array[0..1000000]of longint;
 5 begin
 6         assign(input,'p1313.in');
 7         assign(output,'haha.out');
 8         reset(input);
 9         rewrite(output);
10         read(n,m);
11         for i:=1 to n do
12                 read(s[i]);
13         for i:=1 to n do
14                 f[i]:=s[i];
15         w:=0;
16         for i:=1 to m do
17                 begin
18                 while(w>=0)and(f[d[w]]>f[i])do dec(w);
19                 inc(w);
20                 d[w]:=i;
21                 end;
22         for i:=m+1 to n do
23                 begin
24                 while d[t]<i-m do inc(t);
25                 f[i]:=f[i]+f[d[t]];
26                 while(w>=t)and(f[d[w]]>f[i])do dec(w);
27                 inc(w);
28                 d[w]:=i;
29                 end;
30         ans:=maxlongint;
31         for i:=n-m+1 to n do
32                 if ans>f[i] then ans:=f[i];
33         write(ans);
34         close(input);
35         close(output);
36 end.                        

转载于:https://www.cnblogs.com/zyxx233/archive/2012/12/01/2797678.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值