• 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
    */
  • 相关阅读:
    c语言中程序的循环控制 大小值的判断及赋值
    python中猜数字小游戏
    R语言中自编函数(例题)
    c语言中continue语句
    c语言中程序的循环控制 变量的非常规变化例题
    python中向列表中添加元素
    mean
    python中原始字符串和长字符串
    ArcInfo 的工作空间和 Coverage
    ArcGIS资料大全
  • 原文地址:https://www.cnblogs.com/tempestT/p/10673515.html
Copyright © 2020-2023  润新知