http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2249
Description
A set of frogs have accidentally fallen to the bottom of a large pit. Their only means of escaping the pit is to jump out of it. Each frog i is described by three parameters (li, wi, hi) where li is its leap capacity, wi its weight, and hi its height. The leap capacity specifies how high that frog can jump. If a frog's leap capacity is strictly larger than the depth of the pit, the frog can directly escape the pit. However, these frogs are altruistic. Rather than selfishly saving themselves and leaving the frogs with too limited leap capacity behind, they collectively aim to save as many of them from the pit as possible.
The frogs realize that if a frog A climbs up on the back of frog B before it jumps, the first frog A stands a better chance of escaping the pit: it can escape if hB + lA is strictly larger than the depth of the pit.
Furthermore, if frog B carrying frog A on its back climbs up on the back of frog C, the situation is even better for frog A: it can now escape the pit if hC + hB + lA is strictly larger than the depth of the pit.
The frogs can build even higher piles of frogs this way, the only restriction is that no frog may carry other frogs of weight in total amounting to its own weight or heavier. Once a pile has been used to allow a frog to escape, the frogs in the pile jump back to the bottom of the pit and they can then form a new pile (possibly consisting of a different set of frogs). The question is simply how many frogs can escape the pit assuming they collaborate to maximize this number?
Input
The first line of input contains two integers n and d (1 ≤ n ≤ 100 000, 1 ≤ d ≤ 108), where n is the number of frogs and d is the depth of the pit in µm. Then follow n lines each containing three integers l, w, h (1 ≤ l, w, h ≤ 108), representing a frog with leap capacity l µm, weight w µg, and height h µm. The sum of all frogs' weights is at most 108 µg.
Output
Output the maximum number of frogs that can escape the pit.
Sample Input
3 19 15 5 3 12 4 4 20 10 5
Sample Output
3
题目大意:一口深为h的井中有n只青蛙,给出它们的弹跳能力、重量、高度,青蛙可以叠在一起,但要满足任意一只青蛙之上的青蛙的重量之和小于这只青蛙,当某只青蛙现在所处的高度+其弹跳能力>h时,这只青蛙可以跳出,问最多可以使多少只青蛙跳出。
思路:首先贪心的想一下,有一只比较重的青蛙和一直比较轻的青蛙,我们肯定倾向于让轻的青蛙跳出去,因为重的青蛙更有可能承载更多的青蛙,因此我们把青蛙按照重量从大到小排序,然后开始dp,我们用dp[i]表示能承载重量为i时所能达到的最高高度,那么对于第j只青蛙,我们只需要更新dp[1]到dp[wj-1]的信息,注意到题目中提到了Σwj<=10^8,因此复杂度是允许的;对于1<=k<=wj-1,有dp[k]=max(dp[k],dp[k+wj]+hj)。可以加一个小优化,我们令sum=Σwj,当k+wj>sum的时候,就不用更新了,因为dp数组是非升的,没必要进行无意义的更新(其实这种情况只会出现在重量最大的那个青蛙上 而有意义的情况最多也不过是所有的青蛙都能叠在一起 那么必定满足k<=sum-w1)。这样做是没有后效性的,因为我们是在前j-1只青蛙的情况下决定第j只青蛙能否跳出去的,因此无论是否能跳出去,它都要留下为后续的青蛙提供选择。(也就是必须要做更新操作)
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
int l,w,h;
bool operator <(const node& a)const
{
return w>a.w;
}
};
node a[100005];
int dp[100000005];
int sum=0;
int n,hi,ans;
int main()
{
scanf("%d %d",&n,&hi);
for(int i=0;i<n;i++)
{
scanf("%d %d %d",&a[i].l,&a[i].w,&a[i].h);
sum+=a[i].w;
}
sort(a,a+n);
int MAX=0;
for(int i=0;i<n;i++)
{
if(dp[a[i].w]+a[i].l>hi)
++ans;
for(int j=1;j<a[i].w;j++)
{
dp[j]=max(dp[j],dp[j+a[i].w]+a[i].h);
if(j+a[i].w>=sum)
break;
}
}
printf("%d\n",ans);
return 0;
}