1 条题解
-
0
非常有趣的一道题,乍一看很鬼,实际上仔细思考一下就能得到答案。
闲话少说,切入正题——
首先,我们来想想这个小矮人排列的大致次序。
如果把高的给弄出去,那么这个贡献没了,很有可能导致只有这个高的一个人出去剩下的矮子全出不去的情况。
那么矮的弄出去呢?显然,矮的弄出去对人梯的高度损失是最小的,也可以让更多的矮子出去。
综上所述,我们就按照 从小到大排列矮人。
然后问题来了,我们应该如何统计答案呢?
可以用 dp 鸭~
设 为当前出去了 个人能堆起来最高的高度(不算手)。
要不然, 号小矮人不出去, 还是 。
要不然, 号小矮人滚出去, 就变成了 。
所以状态转移方程就出来了:。
上代码!
#include<iostream> #include<algorithm> #include<cstring> using namespace std; struct node{ int a,b; }A[2021]; bool cmp(node &x,node &y)//排序比较器 { return x.a+x.b<y.a+y.b; } int f[2021]; int main() { memset(f,128,sizeof(f));//这里的 128 运用到了补码原理,总之你只要知道是最小值就好了。 int n,h; cin>>n; for(int p=1;p<=n;p++) cin>>A[p].a>>A[p].b; cin>>h; sort(A+1,A+n+1,cmp);//排序 f[0]=0;//没人出去 for(int p=1;p<=n;p++)//初始化没人出去的情况,显然这个时候要累加 a[p] f[0]+=A[p].a; for(int p=1;p<=n;p++)//根据上面的方程 dp for(int i=p;i>=1;i--) if(f[i-1]+A[p].b>=h)//如果算上这个人的手能出去 f[i]=max(f[i],f[i-1]-A[p].a); for(int p=n;p>=0;p--) if(f[p]>=0) { cout<<p<<endl; return 0; } }
- 1
信息
- ID
- 4839
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者