2014-03-21 22:05

题目:给你N个盒子堆成一座塔,要求下面盒子的长和宽都要严格大于上面的。问最多能堆多少个盒子?

解法1:O(n^2)的动态规划解决。其实是最长递增子序列问题,所以也可以用O(n * log(n))的优化算法。

代码:

// 11.7 n boxes are to stack up to a tower. Every box must be strictly smaller in width and height than the one right below it.
// How many boxes at most can you stack up?
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;

struct Box {
    int x;
    int y;
    Box(int _x = 0, int _y = 0): x(_x), y(_y) {};
    
    bool operator < (const Box &other) {
        if (x != other.x) {
            return x < other.x;
        } else {
            return y < other.y;
        }
    };
};

int main()
{
    vector<Box> v;
    vector<int> dp;
    int n;
    int i, j;
    int res;
    
    while (scanf("%d", &n) == 1 && n > 0) {
        v.resize(n);
        for (i = 0; i < n; ++i) {
            scanf("%d%d", &v[i].x, &v[i].y);
        }
        sort(v.begin(), v.end());
        dp.resize(n);
        res = 0;
        for (i = 0; i < n; ++i) {
            dp[i] = 1;
            for (j = 0; j < i; ++j) {
                if (v[j].x < v[i].x && v[j].y < v[i].y) {
                    dp[i] = dp[j] + 1 > dp[i] ? dp[j] + 1 : dp[i];
                }
            }
            res = dp[i] > res ? dp[i] : res;
        }
        printf("%d\n", res);
        
        v.clear();
        dp.clear();
    }
    
    return 0;
}

解法2:用二分查找优化后的代码,其中使用了STL算法库提供的lower_bound(),二分也不总是要手写的。

代码:

 1 // 11.7 n boxes are to stack up to a tower. Every box must be strictly smaller in width and height than the one right below it.
 2 // How many boxes at most can you stack up?
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <vector>
 6 using namespace std;
 7 
 8 struct Box {
 9     int x;
10     int y;
11     Box(int _x = 0, int _y = 0): x(_x), y(_y) {};
12     
13     bool operator < (const Box &other) {
14         if (x != other.x) {
15             return x < other.x;
16         } else {
17             return y < other.y;
18         }
19     };
20 };
21 
22 int main()
23 {
24     vector<Box> v;
25     vector<int> dp;
26     vector<int>::iterator it;
27     int n;
28     int i;
29     
30     while (scanf("%d", &n) == 1 && n > 0) {
31         v.resize(n);
32         for (i = 0; i < n; ++i) {
33             scanf("%d%d", &v[i].x, &v[i].y);
34         }
35         sort(v.begin(), v.end());
36         dp.push_back(v[0].y);
37         for (i = 1; i < n; ++i) {
38             if (v[i].y > dp[dp.size() - 1]) {
39                 dp.push_back(v[i].y);
40             } else {
41                 it = lower_bound(dp.begin(), dp.end(), v[i].y);
42                 *it = v[i].y;
43             }
44         }
45         printf("%d\n", (int)dp.size());
46         
47         v.clear();
48         dp.clear();
49     }
50     
51     return 0;
52 }

 

 posted on 2014-03-21 22:18  zhuli19901106  阅读(218)  评论(0编辑  收藏  举报