zoukankan      html  css  js  c++  java
  • Luogu1941 飞扬的小鸟

    这题的 dp 还是比较显然的

    听说是个完全背包,大概转移是差不多的
    就从当前层顺着枚举 j 往大去更新同层的就好了

    其实这样每次往高处转移的就是下面的前缀最小值

    值得注意的是题意要模拟的是游戏
    所以显然不能先掉下去在在同一步中往上飞

    所以转移顺序是不能乱的

    就是先转移往上飞的在转移往下掉的

    好像多开一维也行,不过没有必要了


     代码:

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cctype>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    const int MAX_N = 10005, MAX_M = 1005;
    
    int n, m, k, max_dst;
    int x[MAX_N], y[MAX_N], pos[MAX_N], pre_sum[MAX_N];
    int bot[MAX_N], top[MAX_N], f[MAX_N][MAX_M];
    bool has_stk[MAX_N];
    
    int main() {
        scanf("%d%d%d", &n, &m, &k);
        for (int i = 1; i <= n; ++i) scanf("%d%d", &x[i], &y[i]);
        for (int i = 1; i <= k; ++i) {
            scanf("%d", &pos[i]);
            scanf("%d%d", &bot[pos[i]], &top[pos[i]]);
            has_stk[pos[i]] = true;
        }
        for (int i = 1; i < n; ++i) pre_sum[i] = pre_sum[i - 1] + has_stk[i];
        memset(f, 0x3f, sizeof(f));
        for (int i = 1; i <= m; ++i) f[0][i] = 0;
        for (int i = 1; i <= n; ++i) {
            for (int j = x[i] + 1; j <= m; ++j) {
                max_dst = (f[i][j] < 0x3f3f3f3f) ? i : max_dst;
                f[i][j] = min(f[i][j], min(f[i - 1][j - x[i]], f[i][j - x[i]]) + 1);
            }
            for (int j = m - x[i]; j <= m; ++j) {
                max_dst = (f[i][j] < 0x3f3f3f3f) ? i : max_dst;
                f[i][m] = min(f[i][m], min(f[i - 1][j], f[i][j]) + 1);
            }
            for (int j = 1; j <= m - y[i]; ++j) {
                max_dst = (f[i][j] < 0x3f3f3f3f) ? i : max_dst;
                f[i][j] = min(f[i][j], f[i - 1][j + y[i]]);
            }
            if (has_stk[i]) {
                for (int j = 1; j <= bot[i]; ++j) f[i][j] = 0x3f3f3f3f;
                for (int j = top[i]; j <= m; ++j) f[i][j] = 0x3f3f3f3f;
            }
        }
        register int min_res = 0x3f3f3f3f;
        if (!has_stk[n]) {
            for (int i = 1; i <= m; ++i) if (f[n][i] < 0x3f3f3f3f) {
                max_dst = n;
                min_res = min(min_res, f[n][i]);
            }
        } else {
            for (int i = bot[n] + 1; i < top[n]; ++i) if (f[n][i] < 0x3f3f3f3f) {
                max_dst = n;
                min_res = min(min_res, f[n][i]);
            }
        }
        if (max_dst == n) {
            puts("1");
            printf("%d", min_res);
        } else {
            printf("0
    %d", pre_sum[max_dst] - has_stk[max_dst]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored(E F G H I)
    Ubuntu iso下载地址(14、16、18)
    JS解决在提交form表单时某个值不存在 alter弹窗点确定不刷新界面
    搞搞电脑微信表情的破解(.dat转png or jpg)
    12.29 模拟赛
    bzoj 2151 种树
    bzoj 5110 Yazid的新生舞会
    【系列】 点分治
    12.8 模拟赛
    12.17 模拟赛
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9908539.html
Copyright © 2011-2022 走看看