烽火传递(单调队列优化dp)

找了好半天也没找到可以注册&&提交本题得OJ,
所以不能保证AC。

描述
烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上。一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息:夜晚燃烧干柴,以火光传递军情。在某两座城市之间有n个烽火台,每个烽火台发出信号都有一定的代价。为了使情报准确的传递,在m个烽火台中至少要有一个发出信号。现输入n、m和每个烽火台发出的信号的代价,请计算总共最少需要花费多少代价,才能使敌军来袭之时,情报能在这两座城市之间准确的传递!!!

输入格式 Input Format

  第一行有两个数n,m分别表示n个烽火台,在m个烽火台中至少要有一个发出信号。

     第二行为n个数,表示每一个烽火台的代价。

输出格式 Output Format

    一个数,即最小代价。       

样例

5 3

1 2 5 6 2

4

时间限制 Time Limitation

    各个测试点1s

注释 Hint

    1<=n,m<=1,000,000

题解:
一维线性dp,看上去是一眼秒得题。
dp[i]表示传到第i个峰台并且点亮了它时用的总最小代价。
dp[i] = min(dp[i-m]。。。。。dp[i-1]) + a[i]
(如果i-m到i-1中一个都没有点亮,那显然这m个就不符合题中:【每m个至少亮一个】的要求了)
最后dp[n-m+1]。。。。dp[n]中最小的一个即为所求。

但是我们注意到n、m都是1e6的范围。
那么这个的O(n*m)的算法就GG了。

但注意到整个过程,很像滑动窗口那道题,即每m个窗口中我们要选择最小的那个值和a[i]相加来更新dp[i].
我们只需要维护一个单增的队列,队列元素为峰台下标,当前点第i盏灯时,i-m以前的都没用了,不能用他们更新,所以pop_front。
然后队首即为这m个中的最小代价,用它更新dp[i],上一个思路的O(m)部分就省下来了。
然后在把i加入队列之前,把比它大的值都pop_back掉,因为永远用不到它们来更新了,毕竟有离得更近,代价更低的第i盏。

复杂度:每个元素最多进出一次队列,所以并没有什么要担心的。O(n)。

用单调队列优化的dp方法有一定的规律性,简单来说就是可以看出滑动窗口的影子。
即有单调性。一定范围内只会用一个数组中的最大值或者最小值。
比较有名的应用应该是在优化多重背包的时候。
后面会更新到用单纯形法优化dp,算是更加神奇的所在,在我OR(运筹学)的学习中也有所应用。

#include <cstdio>
#include <iostream>
#include <deque>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
deque<LL> q;
LL dp[maxn];
LL a[maxn];
int n,m;
void init(){
    scanf("%d%d",&n,&m);
    for(int  i = 1;i <= n ; i++)
        scanf("%lld",&a[i]);
    q.push_back(0);
}
LL ans = 1e14+10;
void sov(){
    for(int i = 1 ; i <= n ; i++){
        //printf("i = %d\n",i);
        for(auto j:q){
            if(j < i-m && i-m >= 0)
                q.pop_front();
        }
//        for(auto j:q){
//            printf("inqueue: %d\n",j);
//        }
        LL k = q.front();
        dp[i] = dp[k]+a[i];
        while(dp[q.back()]>dp[i])   q.pop_back();
        q.push_back(i);
    }
    for(int i = n-m+1 ; i <= n ; i++){
        ans = min(ans,dp[i]);
    }
    printf("%lld\n",ans);
}
int main(){
    init();
    sov();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • 这个不错分享给大家,从扣上看到的,就转过来了 《电脑专业英语》 file [fail] n. 文件;v. 保存文...
    麦子先生R阅读 6,559评论 5 24
  • 动态规划(Dynamic Programming) 本文包括: 动态规划定义 状态转移方程 动态规划算法步骤 最长...
    廖少少阅读 3,273评论 0 18
  • 遇见你 是毫无准备的惊喜 离开你 是预谋已久的可惜 怀念生活中不期而遇的小甜蜜 怀念爱情里断断续续的小别离 此生,...
    爱听冷笑话的热水壶阅读 196评论 0 2
  • 今天和昨天的回顾合并一起写一写。昨天结束了为期十天的就业培训。 其实每天6小时的学习,难度和强度并不大,只是当把创...
    786d0e7fcf07阅读 125评论 0 0
  • 愉快的开始 一段出现bug的代码如下: HttpsURLConnection conn = (HttpsURLCo...
    haohui谌阅读 1,562评论 0 1