NOIP2010 烽火传递 队列DP

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

f[i]=w[i]+min{f[j]},i-m<=j<=i-1

显然,要省时间就要维护一个单调的,第一个元素只是f[j]中最小值的队列。
我们看看代码:

#include
#include
#define N 100010
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
int f[N];
int que[N];

int main()
{
    scanf("%d%d",&n,&m);
    int head=1,tail=0;
    for(int i=1;i<=n;i++)
    {
        int w;
        scanf("%d",&w);
        while(head<=tail&&f[que[tail]]>=f[i-1])
            tail--;
        que[++tail]=i-1;
        while(que[head]//清理队列中不必要的元素,维护队列内的单调性 
        f[i]=w+f[que[head]];//动态转移方程 
    }
    int ans=inf;
    for(int i=n;i>n-m;i--)
        ans=min(ans,f[i]);
    printf("%d\n",ans);
    return 0;
}

以上

你可能感兴趣的:(单个题解)