UVA - 11003

Boxes

 

  • 給予一個數字N代表有多少個箱子

  • 給予多組序列 {weight, load}

  • weight代表這個箱子本身重量, load代表他能承受的重量

  • 詢問按照順序由上到下最多能夠疊幾個箱子

  • 可以抽取任意的箱子出來,但不能違反順序

  • N <= 1000

不停更新重量

ex.

5

19 15

7 13

5 7

0

     

 

定義結構: (當前箱子層數, 還可以承受多少重量)

假設我們將這個結構暴力去做查找

 

(1,15), (1,13), (1,7), (1,8), (1,2)

再由當前的箱子去對後面所有箱子遍歷,我們會變成

                            (3,3)

                            (2,8)

            (2,8)        (2,10)

(1,15)  (1,13)      (1,7),      ans= 3

但由於我們每疊上一層就得遍歷前面所有箱子,並疊加上去,時間複雜度為O(N^3), TLE

那我們思考一下怎麼壓縮資料

define h[疊多少層] = 能夠承受的最大重量

每次都往後推,並不停更新能夠承受的最大重量,且取大

並每次查看h list (從尾部到頭部)去更新資料

由於先更新頭部可能在後續的疊加中影響結果所以這邊從後面更新起

ex.

5

19 15

7 13

5 7

0

h = [15]

現在取箱子2 並查看他們疊加第1個箱子以後的答案

h = [15, 8]

現在取箱子3 並查看他們疊加其他箱子以後的答案

h = [15, 10, 1]

.... 以此類推, 用excel展示

時間複雜度為O(N^2), AC

dp[j+1]=max(dp[j+1],min(dp[j]v[i].first,v[i].second))

AC code

#include <bits/stdc++.h>
#pragma GCC optimize("O3","unroll-loops")
#define IO cin.tie(0), ios::sync_with_stdio(0)
#define All(x) x.begin(), x.end()
#define sort_unique(x) sort(All(x)); x.erase(unique(All(x)), x.end());
#define ne nth_element  
#define pb push_back
#define pii pair<int, int>
#define INF (int)1e9;
#define ll long long
using namespace std;

int32_t main(){
    IO;
    int n;
    while(cin >> n && n){
        vector<pair<int, int>> v(n);
        for(auto&[w,h]:v) cin >> w >> h;
        vector<int> h(n+1,0);
        h[1] = v[0].second;
        int maxIndex = 1, last = 0;
        for(int i = 1; i < n; i++){
            for(int j = maxIndex; j >= 1; j--){
                h[j+1] = max(h[j+1], min(h[j] - v[i].first, v[i].second));
                if(h[j+1]) maxIndex = max(j+1, maxIndex);
            }
            h[1] = max(h[1], v[i].second);
        }
        cout << maxIndex << endl;
    }
    // define h[how many boxes be superimposed] = max weight can afford
 
}

deck

By rogerdeng

deck

  • 109