Description

一群小矮人掉进了一个很深的陷阱里, 由于太矮爬不上来, 于是他们决定搭一个人梯. 即: 一个小矮人站在另一小矮人的肩膀上, 知道最顶端的小矮人伸直胳膊可以碰到陷阱口. 对于 每一个小矮人, 我们知道他从脚到肩膀的高度 \(A_i\), 并且他的胳膊长度为 \(B_i\). 陷阱 深度为 \(H\). 如果我们利用矮人 \(1\), 矮人 \(2\), 矮人 \(3\), ...... , 矮人 \(k\) 搭一个梯子, 满足 \(A_1 + A_2 + A_3 + \ldots + A_k + B_k \geq H\), 那么矮人 \(k\) 就可以离开陷阱逃跑了, 一旦一个矮人逃跑了, 他就不能再搭人梯了.

我们希望尽可能多的小矮人逃跑, 问最多可以使多少个小矮人逃跑.

Input

第一行一个整数 \(n\), 表示矮人的个数, 接下来 \(n\) 行每一行两个整数 \(A_i\)\(B_i\), 最后一行是 \(H\).

Output

一个整数表示对多可以逃跑多少小矮人

Sample Input

2
20 10
5 5
30

Sample Output

2

Data Range

对于 30% 的数据,\(n \leq 200\)

对于 100% 的数据,\(n \leq 2000, A_i, B_i, H \leq 10^5\)

Explanation

我们发现垫在最底下的小矮人总是上不来, 所以基本上顺序没什么关系.

这样我们钦定个头最高的垫在底下, 好让更多的矮人上来 (高个儿表示不服)

然后发现不停地把人磊上去, 最后确定一个界限, 然后就可以成功求得答案.

似乎是一道比较显著的结论+贪心题~

Source Code


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>

#define maximize(__x,__y) __x=max(__x,__y)
using namespace std;
typedef long long lli;
const int maxn = 2010;

struct dwarf {
    int body, arm; };
bool operator < (dwarf a, dwarf b) {
    return a.body + a.arm < b.body + b.arm; }

int n, H;
int dp[maxn];
dwarf arr[maxn];

int main(int argc, char** argv)
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &arr[i].body, &arr[i].arm);
        dp[0] += arr[i].body;
    }
    scanf("%d", &H);
    sort(arr + 1, arr + 1 + n);
    // Some magical dynamic programming...
    int res = 0;
    for (int i = 1; i <= n+1; i++)
        dp[i] = -1;
    for (int i = 1; i <= n; i++) {
        for (int j = res; j >= 0; j--) {
            if (dp[j] + arr[i].arm >= H)
                maximize(dp[j + 1], dp[j] - arr[i].body);
            if (dp[res + 1] >= 0)
                res += 1;
        }
    }
    // Output results
    printf("%d\n", res);
    return 0;
}