zoukankan      html  css  js  c++  java
  • POJ 2373 Dividing the Path (单调队列优化DP)题解

    思路:

    设dp[i]为覆盖i所用的最小数量,那么dp[i] = min(dp[k] + 1),其中i - 2b <= k <= i -2a,所以可以手动开一个单调递增的队列,队首元素就是k。

    初始状态为dp[0] = 0,注意喷水覆盖的范围是偶数且不重叠,所以插入队列的必是偶数。有牛的地方不能作为边界,所以这些地方都要排除,可以用vis标记或者其他方法。

    代码:

    #include<map>
    #include<ctime>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int N = 1000000+5;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    int dp[N],q[N]; //单调递增队列:队首是当前dp最小的
    int main() {
        int n,l,a,b,L,R;
        scanf("%d%d%d%d",&n,&l,&a,&b);
        memset(dp,INF,sizeof(dp));
        for(int i = 0;i < n;i++){
            scanf("%d%d",&L,&R);
            for(int j = L + 1;j <= R - 1;j++){
                    dp[j] = INF + 1;
            }
        }
        int head = 0,tail = 0;
        dp[0] = 0;
        for(int i = 2*a;i <= l;i+= 2){
            while(head < tail && dp[q[tail - 1]] >= dp[i - 2*a]) tail--;
            q[tail++] = i - 2*a;
            while(head < tail && q[head] < i - 2*b) head++;  //i - 2*b <= j <= i - 2*a
            if(dp[i] <= INF) dp[i] = dp[q[head]] + 1;
        }
        if(dp[l] < INF) printf("%d
    ",dp[l]);
        else printf("-1
    ");
        return 0;
    }
    


  • 相关阅读:
    一个APP爆炸的时代,假设没有wifi
    POJ2393 Yogurt factory 【贪心】
    Levenberg–Marquardt algorithm
    keepalived+nginx安装配置
    測试赛D
    脚本中$
    vm+ubuntu联网
    操作系统从硬件到应用程序之间的关系
    【转】linux驱动开发
    Qt如何重写虚函数
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408780.html
Copyright © 2011-2022 走看看