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
    */
  • 相关阅读:
    条件判断和循环
    list 和tuple的使用
    python的五大数据类型
    简单的一个程序,猜字游戏
    redhat7 nfs的配置以及auto自动挂载
    nmcli添加网卡 并且修改设备名字 添加IP地址
    RHEL7 系统ISCSI存储环境搭建
    Java分布式锁
    24个Jvm面试题总结及答案
    最新天猫3轮面试题目:虚拟机+并发锁+Sql防注入+Zookeeper
  • 原文地址:https://www.cnblogs.com/tempestT/p/10673515.html
Copyright © 2011-2022 走看看