Power oj 2837: 剑道万古如长夜(单调队列优化DP)

题目链接

Description 

李淳罡正在和别人战斗,他一共有 NN 把宝剑,选择每把宝剑都要付出一定的代价。为了能够顺利的战胜敌人,在连续 MM 把宝剑中至少要有一把宝剑要被选择。请计算总共最少花费多少代价,李淳罡才能顺利的战胜敌人

Input 

第一行一个整数 TT (T≤10)(T≤10) ,表示测试数据组数,对于每组测试 :

第二行:两个整数 NN (1≤N≤2⋅106)(1≤N≤2⋅106), MM (1≤M≤N)(1≤M≤N)。其中 NN 表示宝剑的个数, MM 表示在连续 MM 把宝剑中至少要有一把要被选择。

接下来 N行,每行一个数 WiWi (1≤Wi≤105)(1≤Wi≤105),表示选择第 ii把宝剑所需的代价。

Output 

对于每组测试数据,输出一行,表示答案。

1 5 3 1 2 5 6 2

4

题解:中文题,题意不说了。

题解:要是直接写普通DP,复杂度是O(n^2)。这样肯定过不了,现在直接用优先队列来维护最小值,这样复杂度能达到O(n)。

定义状态dp[i]表示,点燃第i个烽火台并保持第1~i个烽火台满足题意(每m个中至少一个被点燃),的最小花费是多少;状态转移方程:dp[i]=mindp[j](i-m=<j<=i-1)+w[i];

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
//#include<unordered_map>
//#include<unordered_set>
const int maxn=2e6+10;
const int mod=1e9+7;
const int inf=1e9;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
#define mid l+(r-l)/2
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI 3.14159265358979323846
int dir[4][2]= {0,-1,-1,0,0,1,1,0};
int dx[]= {-2,-2,-1,-1,1,1,2,2};
int dy[]= {-1,1,-2,2,-2,2,-1,1};
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int a[maxn],que[maxn];
ll dp[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        int head=1,tail=0;
        me(dp,0);
        for(int i=1; i<=n; i++)
        {
            while(head<=tail&&dp[que[tail]]>=dp[i-1])///因为当前i还没有值,只能比较dp[i-1]的值。
                tail--;
            que[++tail]=i-1;
            while(head<=tail&&que[head]<i-m)
                head++;
            dp[i]=a[i]+dp[que[head]];
        }
        ll ans=dp[n];
        for(int i=n-m+1; i<=n; i++)
            ans=min(ans,dp[i]);
        printf("%lld\n",ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值