• poj 3017 单调队列优化动态规划


    思路:dp[i]=min{dp[j]+max(num[j+1]...num[i])},其中sum[i]-sum[j]<=m。

    那么我们需要用单调队列维护j到i的最大值。

    #include<set>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pb push_back
    #define mp make_pair
    #define Maxn 100010
    #define Maxm 200010
    #define Y 1100
    #define LL __int64
    #define Abs(x) ((x)>0?(x):(-x))
    #define lson(x) (x<<1)
    #define rson(x) (x<<1|1)
    #define lowbit(x) (x&(-x))
    #define clr(x,y) memset(x,y,sizeof(x))
    #define Mod 1000000007
    using namespace std;
    LL dp[Maxn],num[Maxn];
    int que[Maxn],head,rear;
    LL sum[Maxn];
    int main()
    {
        int i,j,k,f,n;
        LL m;
        scanf("%d%I64d",&n,&m);
        clr(sum,0);
        clr(dp,0);
        f=0;
        for(i=1;i<=n;i++){
            scanf("%I64d",num+i);
            if(num[i]>m)
                f=1;
            sum[i]=sum[i-1]+num[i];
        }
        if(f){
            printf("-1
    ");
            return 0;
        }
        head=1,rear=0;
        j=0;
        for(i=1;i<=n;i++){
            while(sum[i]-sum[j]>m)
            j++;
            while(que[head]<=j&&head<=rear) head++;
            while(num[que[rear]]<num[i]&&head<=rear) rear--;
            que[++rear]=i;
            dp[i]=dp[j]+num[que[head]];
            for(k=head;k<rear;k++){
                dp[i]=min(dp[i],dp[que[k]]+num[que[k+1]]);
            }
        }
        printf("%I64d
    ",dp[n]);
        return 0;
    }
  • 相关阅读:
    Codeforces Round #171 (Div. 2)
    ACdream 1079 郭式树
    HDOJ 1517 博弈论
    ACdream 1080 面面数
    博弈论 Nim 博弈
    Codeforces Round #172 (Div. 2)
    ACdream 1084 同心树
    STL bitset
    博弈论 bash博弈
    POJ 3261 后缀数组
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3331009.html
Copyright © 2020-2023  润新知