單調隊列+DP

烽火傳遞

 Description  

    烽火臺又稱烽燧,是重要的防禦設施,一般建在險要處或交通要道上。一旦有敵情發生,白天燃燒柴草,通過濃煙表達信息:夜晚燃燒乾柴,以火光傳遞軍情。在某兩座城市之間有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


 表示被這題坑了快3個多小時了,主要還是DP沒學好啊,最後一個for循環很巧妙,之前想了好久都沒想到這點,還用了兩個單調隊列。。。悲劇阿。。。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX ((1<<31)-1)
using namespace std;

int value[1000010],Q[1000010],dp[1000010]={0};


int main()
{
    int ans=MAX;
    int i,n,m,front=0,rear=0;
    scanf("%d %d",&n,&m);

    for(i=1;i<=n;i++)
    {
        scanf("%d",&value[i]);
        while(front<=rear&&(dp[Q[rear-1]]>dp[i-1]))
            rear--;
        Q[rear++] = i-1;
        while(front<rear&&(i-Q[front])>m)
             front++;
        dp[i]=dp[Q[front]]+value[i];
    }
    // for(i=1;i<=n;i++)
    //     printf("%d\n",dp[i]);
    for(i=n;i>=n-m+1;i--)
    {
        if(ans>dp[i])
            ans = dp[i];
    }
        printf("%d\n",ans);
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章