zoukankan      html  css  js  c++  java
  • 一本通 1602:烽火传递

    题目描述

    烽火台是重要的军事防御设施,一般建在交通要道或。
    一旦有军情发生,则白天用浓烟,晚上有火光传递军。
    在某两个城市之间有n座烽火台,每个烽火台发出信。
    为了使情报准确传递,在连续 m
    个烽火台中至少要有一个发出信号。
    现在输入 n,m
    和每个烽火台的代价,请计算在两城市之间准确传递情报所需花费的总代价最少为多少。

    输入样例

    5 3
    1 2 5 6 2
    

    输出样例

    4
    

    算法1

    (普通DP)

    考虑DP,dp[i][j]表示当前已选至i,其中有j个烽火台没有选.
    可得状态转移方程:

    f[i]:=min{f[j]}+a[i](i-m<=j<i-1)
    

    很明显超时。

    C++ 代码

    不能才不会写呢!
    

    算法2(单调队列优化)

    因为要找最小的,就可以想到单调队列,里面存储的值就是到那个点的最小代价.

    时间复杂度

    能过,(肯定不是因为我算不来才不写(⊙o⊙)…)

    C++ 代码

    #include<bits/stdc++.h>
    using namespace std;
    const int INF=1e9;
    const int N=1e6+10;
    int n,m,l,r;
    int a[N],f[N],q[N<<1];
    /*
        队列中每个点就是以他自己开头的m个烽火台的最小总代价.
        也可能没有m个,如<m的.
        最后遍历一遍n-m+1~n,取其中最小的.
    */
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        l=r=0;
        for(int i=1;i<=n;i++){
            while(l<r&&i-q[l]>m) l++;//如果不是i个内,就出队.
            f[i]=f[q[l]]+a[i];
            while(l<r&&f[q[r]]>f[i]) r--;
            q[++r]=i;
        }
        int ans=INF;
        for(int i=n-m+1;i<=n;i++) ans=min(ans,f[i]);
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    对Spring Boot 及Mybatis简单应用
    云时代架构读后感(十)
    云时代架构读后感(九)
    云时代架构读后感(八)
    云时代架构读后感(七)
    云时代架构读后感(六)
    关于mysql,sqlserverl,与oracle数据库连接总结
    云时代架构读后感(五)
    javaweb实现添加课程
    javaweb入门(使用SQLserver2008 R2数据库)
  • 原文地址:https://www.cnblogs.com/Fast-Bird/p/11851565.html
Copyright © 2011-2022 走看看