Save the dwarfs
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 934 Accepted Submission(s): 285
Problem Description
Several dwarfs are trapped in a deep well. They are not tall enough to climb out of the well, so they want to make a human-pyramid, that is, one dwarf stands on another's shoulder, until the dwarf on the top can reach the top of the well when he raise his arms
up. More precisely speaking, we know the i-th dwarf's height from feet to shoulder is Ai, and his arm length Bi. And we know the height of the well is H. If we can build a dwarf-tower consists of dwarf 1, dwarf 2, ..., dwarf k from bottom to top, such that
A1 + A2 + ... + Ak-1 + Ak + Bk >= H, then dwarf k can escape from the well. Obviously, the escaped dwarf can't be used to build tower again.
We want the escaped dwarfs as many as possible. Please write a program to help the dwarfs.
We want the escaped dwarfs as many as possible. Please write a program to help the dwarfs.
Input
The first line of each test case contains N, (1 <= N <= 2000) the number of trapped dwarfs. Each of the following N lines contains two integers Ai and Bi. The last line is H, the height of the well. All the integers are less than 100,000.
Output
Output one line for each test case, indicating the number of dwarfs escaped at most.
Sample Input
2 20 10 5 5 30 2 20 10 5 5 35
Sample Output
2 1HintFor the first case, the tall dwarf can help the other dwarf escape at first. For the second case, only the tall dwarf can escape.
DP?
转自标准题解
dp[i][j]表示最后i个人能逃出j个时,需要之前井中剩下的人的最小A高度之和。
d[]按a+b从大到小排序
dp[i][j] = min(dp[i-1][j] - d[i].a, max(dp[i-1][j-1], h - sumA[i] -s[i].b ))
----------------
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=2222;
const int INF=1e9;
int n,h;
struct dwarfs{
int a;
int b;
}d[maxn];
int f[maxn][maxn];
int sum[maxn];
int ans;
bool cmp(dwarfs x,dwarfs y)
{
return (x.a+x.b)>(y.a+y.b);
}
int main()
{
while (~scanf("%d",&n))
{
memset(f,0,sizeof(f));
sum[0]=0;
for (int i=1;i<=n;i++)
{
scanf("%d%d",&d[i].a,&d[i].b);
}
scanf("%d",&h);
sort(d+1,d+n+1,cmp);
for (int i=1;i<=n;i++)
{
sum[i]=sum[i-1]+d[i].a;
}
for (int i=0;i<=n;i++)
{
for (int j=0;j<=n;j++)
{
f[i][j]=INF;
}
}
f[0][0]=0;
for (int i=1;i<=n;i++)
{
for (int j=0;j<=i;j++)
{
f[i][j]=f[i-1][j]-d[i].a;
int tmp;
if (j>0) tmp=max(f[i-1][j-1],h-sum[i]-d[i].b);
else tmp=h-sum[i]-d[i].b;
if (tmp<f[i][j]) f[i][j]=tmp;
if (f[i][j]<0) f[i][j]=0;
}
}
for (int j=n;j>=0;j--)
{
if (f[n][j]<=0)
{
ans=j;
break;
}
}
printf("%d\n",ans);
}
return 0;
}

本文探讨了一个深井逃脱问题,其中矮人通过搭建人体金字塔来达到井口的高度。通过动态规划算法,计算出最多可以有多少矮人成功逃脱。文章详细介绍了算法的实现过程、关键步骤和优化策略,旨在帮助理解如何使用动态规划解决实际问题。

192

被折叠的 条评论
为什么被折叠?



