zoukankan      html  css  js  c++  java
  • 烽火传递【单调队列优化dp】

    题目大意:

    1.给出长度为n的数组,要求每m个连续的元素之间必须选一个值作为代价,求该数组的最小代价。

    题解思路:

    1.显然是线性dp,dp【i】表示选择第 i 个元素时的最小总代价。很明显状态转移方程为 dp[i] = min(dp[j]) + a[i]。(i - m <= j <= i - 1)。但是在求min(dp[j])的时候,我们需要遍历一遍长度为m大小的区间,m极限与n同大。时间负责度0(N^2)。显然会超时。

    2.我们需要用单调队列来维护长度为m大小区间内的最小值,队头即为最小值,直接O(1)得到min(dp[j]),就可以避免超时。

    代码如下:

     1 #include<stdio.h>
     2 #include<deque>
     3 #include<algorithm>
     4 const int MAXN = 2e5 + 100;
     5 using namespace std;
     6 const int inf = 0x3f3f3f3f;
     7 
     8 int n, m, a[MAXN];
     9 int dp[MAXN]; //表示第 i 个烽火台放置烽火时的最小总代价 
    10 deque<int> Q;
    11 
    12 int main()
    13 {
    14     scanf("%d%d",&n, &m);
    15     for(int i = 1; i <= n; i ++)
    16         scanf("%d", &a[i]);
    17     for(int i = 1; i <= m; i ++)  //dp以及单调队列初始化 
    18     {
    19         dp[i] = a[i];
    20         while(!Q.empty())
    21         {
    22             if(dp[i] < dp[Q.back()])//保证队头保存的是dp值最小的下标 队头到队尾单调递增 
    23                 Q.pop_back();
    24             else
    25                 break;
    26         }
    27         Q.push_back(i);
    28     }
    29     for(int i = m + 1; i <= n; i ++)
    30     {
    31         while(!Q.empty())
    32         {
    33             if(i - m > Q.front()) //保证队头位于枚举范围内,即是在 [i - m, i - 1]范围内 
    34                 Q.pop_front();
    35             else
    36                 break;
    37         }
    38         dp[i] = dp[Q.front()] + a[i];
    39         while(!Q.empty())
    40         {
    41             if(dp[i] < dp[Q.back()])
    42                 Q.pop_back();
    43             else
    44                 break;
    45         }
    46         Q.push_back(i);
    47     }
    48     int ans = inf;
    49     for(int i = n; i > n - m; i --)
    50         ans = min(ans, dp[i]);
    51     printf("%d
    ", ans);
    52     return 0;
    53 }
    54 /*
    55 5 3
    56 1 2 5 6 2
    57 
    58 4
    59 */ 
    View Code
  • 相关阅读:
    Help-C#-属性-生成事件:预先生成事件和后期生成事件
    小说-长篇小说:《追风筝的人》
    散文-笔记:《皮囊》
    小说-励志:《妥协的力量》
    ons.ONSFactory.cs
    ons.ONSFactoryAPI.cs
    ons.ONSFactoryPorperty.cs
    System.Object.cs
    ons.MessageOrderListener.cs
    ons.MessageLisenter.cs
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11929211.html
Copyright © 2011-2022 走看看