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;
    }
    


  • 相关阅读:
    Vue 兄弟组件通信(不使用Vuex)
    vue2.0 #$emit,$on的使用
    Bootstrap栅格系统基本使用
    字体图标使用
    js事件委托
    帆布小球碰壁效果
    vuex -- vue的状态管理模式
    JavaScript --经典问题
    总结获取原生JS(javascript)基本操作
    git的基本操作
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408780.html
Copyright © 2011-2022 走看看