题意

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

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

思路

已知两个相邻的小矮人\(a\)和\(b\),考虑交换\(ab\)位置的代价

首先如果\(a\)在\(b\)下面,那么第一次的高度是\(a.a+b.a+b.b\),第二次的高度是\(a.a+a.b\)

然后如果\(b\)在\(a\)下面,那么第一次的高度是\(a.a+b.a+a.b\),第二次的高度是\(b.a+b.b\)

我们要考虑的就是交换ab会对原来的答案有什么影响

比较直观的想法是关键看第二次的高度,因为第二次的高度更高的那个,最终一定比另一个优。

还要考虑可能会出现的第二个比另一个更高但是第一个不如另一个的情况。

即可能出现\(a.a+a.b>b.a+b.b\),但是\(a.a+b.a+b.b<a.a+b.a+a.b\),即\(a.b>a.a+b.b\)。要知道这是完全可能的

考虑在这种情况下,假设\(a.b>a.a+b.b\),那不交换的情况下第一次是\(a.a+b.a+b.b<a.b+b.a<b.b+a.b+a.a\)因此交换完还是更优

所以只需\(a.a+a.b<a.a+b.b\)即可

上面我们已经证明按贪心完的顺序取是最优的,但是还要确定最多能走掉多少个

接下来要\(dp\):令\(f[i]\)表示走完i个矮人之后还能取到的最大高度

这样贪心的作用就出来了:按照贪心完的顺序取走矮人,可以保证最优。

一开始初始化\(f[0]\)表示没有矮人走掉,\(f[0]=Σa[i]\)。

然后就是枚举取到第i个矮人,可以用它来更新\(f[j]\)的情况是\(f[j]+ai.b>=m\)。

这样就可以算出最大值了

代码

  1. # include<bits/stdc++.h>
  2. using namespace std;
  3. # define lowbit(x) ((x)&(-x))
  4. # define pi acos(-1.0)
  5. # define eps 1e-8
  6. # define MOD 100000007
  7. # define INF 1000000000
  8. # define mem(a,b) memset(a,b,sizeof(a))
  9. # define FOR(i,a,n) for(register int i=a; i<=n; ++i)
  10. # define FDR(i,a,n) for(register int i=a; i>=n; --i)
  11. # define bug puts("H");
  12. # define lch p<<1,l,mid
  13. # define rch p<<1|1,mid+1,r
  14. # define mp make_pair
  15. # define pb push_back
  16. typedef pair<int,int> PII;
  17. typedef vector<int> VI;
  18. # pragma comment(linker, "/STACK:1024000000,1024000000")
  19. typedef long long LL;
  20. inline char nc(){
  21. static char buf[1000000],*p1=buf,*p2=buf;
  22. return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
  23. }
  24. inline int Scan(){
  25. char ch=nc();int sum=0, f=1;
  26. if (ch=='-') f=-1, ch=nc();
  27. while(!(ch>='0'&&ch<='9'))ch=nc();
  28. while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
  29. return sum*f;
  30. }
  31. const int N=2005;
  32. //Code begin....
  33. struct Node{int x, y;}node[N];
  34. int dp[N];
  35. bool comp(Node a, Node b){return a.x+a.y<b.x+b.y;}
  36. int main ()
  37. {
  38. int n, ans, H;
  39. scanf("%d",&n);
  40. mem(dp,-1); dp[0]=0;
  41. FOR(i,1,n) scanf("%d%d",&node[i].x,&node[i].y), dp[0]+=node[i].x;
  42. scanf("%d",&H);
  43. sort(node+1,node+n+1,comp);
  44. FOR(i,1,n) FDR(j,i,1) if (dp[j-1]+node[i].y>=H) dp[j]=max(dp[j],dp[j-1]-node[i].x);
  45. FDR(i,n,0) if (dp[i]!=-1) {ans=i; break;}
  46. printf("%d\n",ans);
  47. return 0;
  48. }

BZOJ 3174 拯救小矮人(贪心+DP)的更多相关文章

  1. 【BZOJ-3174】拯救小矮人 贪心 + DP

    3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 686  Solved: 357[Submit][Status ...

  2. 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp

    题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...

  3. [TJOI2013] 拯救小矮人- 贪心,dp

    结论:矮的人比高的人先走一定不会使得答案变劣 于是我们排序后,像 0-1 背包那样依次考虑每个人走不走 #include <bits/stdc++.h> using namespace s ...

  4. BZOJ3174. [TJOI2013]拯救小矮人(dp)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3174 题解 其实此题并不需要那么多YY的部分. 我们考虑若干个小矮人逃出的顺序.若跳出的 ...

  5. [TJOI2013]拯救小矮人[排序+dp]

    题意 题目链接 分析 Imagine的完美回答 重点大概是证明我们选出要救的小矮人一定可以根据 \(a_i+b_i\) 的大小进行排序救出. 注意这里关注的对象是可以保留的高度,所以我们的dp值才会表 ...

  6. BZOJ3174 TJOI2013 拯救小矮人 贪心、DP

    传送门 原问题等价于:先给\(n\)个人排好顺序.叠在一起,然后从顶往底能走即走,问最多能走多少人 注意到一个问题:如果存在两个人\(i,j\)满足\(a_i + b_i < a_j + b_j ...

  7. BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP

    BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...

  8. 贪心+DP【洛谷P4823】 [TJOI2013]拯救小矮人

    P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...

  9. 【BZOJ3174】[TJOI2013]拯救小矮人(贪心,动态规划)

    [BZOJ3174][TJOI2013]拯救小矮人(贪心,动态规划) 题面 BZOJ 洛谷 题解 我们定义一个小矮人的\(A_i+B_i\)为它的逃跑能力. 我们发现,如果有两个小矮人\(x,y\), ...

随机推荐

  1. Xcode 备忘

    一. 打印一堆乱七八糟的东西: Edit Scheme... --> Run --> Arguments,在 Environment Variables 里添加 OS_ACTIVITY_M ...

  2. 一个将lambda字符串转化为lambda表达式的公共类

    一个将lambda字符串转化为lambda表达式的公共类.StringToLambda 使用方式如下: var module = new Module(); url = url.ToLower();/ ...

  3. ASP.NET Core 中 HttpContext 详解与使用 | Microsoft.AspNetCore.Http 详解

    笔者没有学 ASP.NET,直接学 ASP.NET Core ,学完 ASP.NET Core MVC 基础后,开始学习 ASP.NET Core 的运行原理.发现应用程序有一个非常主要的 “传导体” ...

  4. NYOJ 35 表达式求值

    一个模板了 哈哈. 这题由于已经包括了整形.浮点形了,以后也不须要特别处理了. /* 这里主要是逆波兰式的实现,使用两个stack 这里用字符串来模拟一个stack,第一步,将中缀表达式转变为后缀表达 ...

  5. 一文让您全面了解清楚HBase数据库的所有知识点,值得收藏!

    一.HBase基本概念:列式数据库 在Hadoop生态体系结构中,HBase位于HDFS(Hadoop分布式文件系统)的上一层,不依赖于MapReduce,那么如果没有HBase这种Nosql数据库会 ...

  6. CS229笔记:分类与逻辑回归

    逻辑回归 对于一个二分类(binary classification)问题,\(y \in \left\{0, 1\right\}\),如果直接用线性回归去预测,结果显然是非常不准确的,所以我们采用一 ...

  7. C#Unit单元测试之读取Web.config文件

    长期一来,我们所完成的项目都没有写单元测试,今天我一时兴起,决定给自己写的代码写单元测试,简单的测试代码分分钟完成了,一运行测试,就懵逼了.没能达到我的预期效果,而是出现图1所示错误. 图1:单元测试 ...

  8. springboot打包成war后部署项目出现异常 LifecycleException: Failed to start component

    完整异常:org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].Sta ...

  9. 页面弹出全屏浮层或遮罩时,禁止底层body滚动

    · 解决方法 针对弹出的浮层的 touchmove事件,添加阻止浏览器默认行为. $('.mask-wrapper').on('touchmove', function (event) { // 监听 ...

  10. JVM技术周报第1期

    JVM技术周报 · 第1期 JVM技术每周分享整理了JVM技术交流群每周讨论的内容,由群内成员整理归纳而成.如果你有兴趣入群讨论,请关注「Java技术精选」公众号,通过右下角菜单「入群交流」加我好友, ...