zoukankan      html  css  js  c++  java
  • B. Shaass and Bookshelf DP

    http://codeforces.com/contest/294/problem/B

    据说是贪心,我用了一个复杂度是2e8的dp水过去了。

    其实这题就是给你n个数,每个数有两个权值,分成两组,使得第一个权值之和,和第二个权值之和的最大值最小。

    那么直接设dp[i][j][k][h]表示前i个数中,选了j个,第一个权值的和是k,第二个权值是h,是否可能。

    这里是一定要选出n个的,就是n个数都必须使用,才能滚动数组。(把第二维滚动)

    如果是从n个数中选出k个,那么就不能滚动了。

    那么第一维是01背包直接省略,j那里可以滚动数组。

    总复杂度2e8

    然后题解是贪心......

    还有要注意,k要大于h,就是底下的书要长于上面的书。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    struct node {
        int ti, wi;
    }a[111];
    int dp[2][200 + 2][10000 + 2];
    void work() {
        int n;
        cin >> n;
        int DFN = 1;
        int sumti = 0, sumwi = 0;
        for (int i = 1; i <= n; ++i) {
            cin >> a[i].ti >> a[i].wi;
            sumti += a[i].ti;
            sumwi += a[i].wi;
        }
        if (n == 1) {
            cout << min(a[1].ti, a[1].wi) << endl;
            return;
        }
    //    sort(a + 1, a + 1 + n);
        dp[0][0][0] = DFN;
        int now = 0;
        for (int i = 1; i <= n; ++i) {
            now = !now;
            ++DFN;
            for (int j = sumti; j >= 0; --j) {
                for (int k = sumwi; k >= 0; --k) {
                    if (j >= a[i].ti && dp[!now][j - a[i].ti][k] == DFN - 1) {
                        dp[now][j][k] = DFN;
                    }
                    if (k >= a[i].wi && dp[!now][j][k - a[i].wi] == DFN - 1) {
                        dp[now][j][k] = DFN;
                    }
                }
            }
        }
        int ans = inf;
        for (int i = 0; i <= sumti; ++i) {
            for (int j = 0; j <= i; ++j) {
                if (dp[now][i][j] == DFN) {
                    ans = min(ans, max(i, j));
                }
            }
        }
        cout << ans << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    node-sass 安装失败
    js中复制功能总结
    设置NODE_ENV=test环境变量
    js eslint语法规范错误提示代码
    npm安装node包时怎么显示安装进度
    前端面试题总结三
    5种方式将数字转成千分位
    前端面试题总结二(js原型继承)
    前端面试题总结一(js变量和函数声明提前相关)
    1109 Group Photo (25分)
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6238454.html
Copyright © 2011-2022 走看看