zoukankan      html  css  js  c++  java
  • Codeforces 939F Cutlet dp + 单调队列

    Cutlet

    写出转移方程式, 发现能用单调队列优化, 写起来比较麻烦。

    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 1e5 + 10;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 998244353;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}
    
    int dp[107][100007][2];
    int n, k, l[107], r[107];
    int que[N], be, ed;
    
    int main() {
        memset(dp, 0x3f, sizeof(dp));
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= k; i++) scanf("%d%d", &l[i], &r[i]);
        l[k + 1] = 2 * n;
        dp[0][l[1]][0] = 0;
        dp[0][l[1]][1] = 1;
        dp[0][0][1] = 0;
        dp[0][0][0] = 1;
        for(int i = 1; i <= k; i++) {
            int pt = 0, len = r[i] - l[i];
            be = 1, ed = 0;
            for(int j = 0; j <= n; j++) {
                if(j - len >= 0) dp[i][j][0] = dp[i - 1][j - len][0];
                dp[i][j][1] = dp[i - 1][j][1];
            }
            for(int j = 0; j <= n; j++) {
                while(pt <= j) {
                    while(ed >= be && dp[i - 1][pt][0] <= dp[i - 1][que[ed]][0]) ed--;
                    que[++ed] = j;
                    pt++;
                }
                while(que[be] + len < j) ++be;
                chkmin(dp[i][j][1], dp[i - 1][que[be]][0] + 1);
            }
            be = 1, ed = 0, pt = 0;
            for(int j = 0; j <= n; j++) {
                while(pt <= j) {
                    while(ed >= be && dp[i - 1][pt][1] <= dp[i - 1][que[ed]][1]) ed--;
                    que[++ed] = j;
                    pt++;
                }
                while(que[be] + len < j) ++be;
                chkmin(dp[i][j][0], dp[i - 1][que[be]][1] + 1);
            }
            for(int j = 0; j <= n; j++) {
                chkmin(dp[i][j][0], dp[i][j][1] + 1);
                chkmin(dp[i][j][1], dp[i][j][0] + 1);
            }
            int t = l[i + 1] - r[i];
            if(t) {
                for(int j = n; j >= 0; j--) {
                    if(j + t <= n) {
                        chkmin(dp[i][j + t][0], dp[i][j][0]);
                        chkmin(dp[i][j + t][1], dp[i][j][0] + 1);
                    }
                    dp[i][j][0] = inf;
                }
            }
        }
        if(dp[k][n][0] >= inf) puts("Hungry");
        else {
            puts("Full");
            printf("%d
    ", min(dp[k][n][0], dp[k][n][1]));
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    有没有对象???new一个???
    原生数组的方法--翻转
    rclone的基本用法
    golang 文件操作
    记一次挖矿程序处理 firstpress
    python 第三方库 网络 requests
    python 第三方库 时间 arrow
    ansible playbook loop 翻译
    硬盘性能测试工具之bonnie++
    磁盘性能测试工具之fio
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11029010.html
Copyright © 2011-2022 走看看