zoukankan      html  css  js  c++  java
  • Petrozavodsk Winter Camp, Day 8, 2014, Ship

    $dp(i,j)$表示i~j这段还没运走时的状态,包括 运输了多少次,还剩多少空间

    每次枚举运输左边还是右边转移

    #include <bits/stdc++.h>
    #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i) 
    #define dwn(i, j, k) for (int i = int(j); i >= int(k); -- i)
    using namespace std;
    typedef pair<int, int> P;
    const int N = 1e4 + 7;
    P dp[2][N];
    int w[N];
    
    int main() {
        int n, t;
        scanf("%d%d", &t, &n);
        rep(i, 1, n) scanf("%d", w + i); P tmp;
        auto Enlarge = [&](P &a, P &b) {
            if (a.first == -1) a = b;
            else {
                if (a.first > b.first || (a.first == b.first && a.second < b.second)) a = b;
            }
        };
        for (int i = 1; i <= n; ++ i) dp[(n & 1)][i].first = -1;
        dp[(n & 1)][1] = P(0, 0);
        dwn(l, n, 1) { // i, j 之间还没消去
            int cur = l & 1, next = cur ^ 1;
            // cout << l << ' ' << dp[cur][3].first << ' ' << dp[cur][3].second << '
    ';
            for (int i = 1; i <= n; ++ i) dp[next][i].first = -1;
            for (int i = 1; i + l - 1 <= n; ++ i) 
                if (dp[cur][i].first != -1) {
                    int j = i + l - 1;
                    // 选第i个
                    if (w[i] <= dp[cur][i].second) {
                        tmp = P(dp[cur][i].first, dp[cur][i].second - w[i]);
                        Enlarge(dp[next][i + 1], tmp);
                    }
                    else {
                        tmp = P(dp[cur][i].first + 1, t - w[i]);
                        Enlarge(dp[next][i + 1], tmp);
                    }
                    // 选第jge
                    if (w[j] <= dp[cur][i].second) {
                        tmp = P(dp[cur][i].first, dp[cur][i].second - w[j]);
                        Enlarge(dp[next][i], tmp);
                    }
                    else {
                        tmp = P(dp[cur][i].first + 1, t - w[j]);
                        Enlarge(dp[next][i], tmp);
                    }
    
                }
        }
        // cout << dp[0][3].first << ' ' << dp[0][3].second << '
    ';
        int ans = 10000000;
        for (int i = 1; i <= n; ++ i) 
            if (dp[0][i].first != -1)
                ans = min(ans, dp[0][i].first);
        printf("%d
    ", ans);
    
    }
    /*
    4 5
    1 1 3 1 2
    */
  • 相关阅读:
    [USACO09Open] Tower of Hay 干草塔
    [HNOI2004]打鼹鼠
    BZOJ1222[HNOI 2001]产品加工
    BZOJ1270[BJWC2008]雷涛的小猫
    NOIP2018出征策
    解析·NOIP·冷门 CLZ最小环
    CCF-NOIP-2018 提高组(复赛) 模拟试题(九)(2018 CSYZ长沙一中)
    [脚本无敌1]图片批量处理(matlab)
    用Matlab解《2013年数据建模比赛》图像碎片拼接题
    火灾检测-fire,fire
  • 原文地址:https://www.cnblogs.com/tempestT/p/10673515.html
Copyright © 2011-2022 走看看