洛谷P4823 拯救小矮人 [TJOI2013] 贪心+dp

正解:贪心+dp

解题报告:

传送门!

我以前好像碰到过这题的说,,,有可能是做过类似的题qwq?

首先考虑这种显然是dp?就f[i][j]:决策到了地i个人,跑了j个的最大高度,不断更新j的上限就得到答案了(显然i可以省略但为了表述更清晰一点就懒得省辣?

然后这时候就考虑一个问题,就是,dp的要求是无后效性嘛,但这里有个问题,假如有三个人,高度分别为(1,1)(1,1)(100,100),然后洞的深度是100,如果直接按这个顺序dp,那就只有最后一个人能跑出去了,但实际上只要我们合理安排一下顺序他们都能出去的

所以考虑怎么样的顺序是欧克的

那像这样子贪心决定顺序之类的有个很基本的套路,叫微扰法,就直接单独提出两个来然后交换位置看影响嘛

首先显然如果只有一个人能跑出去就都一样儿了,反正是要dp,我们就不care到底怎么排了反正结果是一样的

但是如果两个人都能跑出去,那肯定是逃生能力大的后跑,这里的逃生能力指的是a+b的那个值

综上,通过贪心可得,先对所有人按a+b排序,然后dp一下就好,over!

然后我在重载<的时候把gd和gs打混了,,,然后我过了几万组拍,,,?我也布吉岛我怎么做到的TT

 

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rc register char
#define rb register bool
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
 
const int N=2000+10;
int n,m,f[N],as;
struct node{int a,b;}nod[N];
 
il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il bool operator < (node gd,node gs){return gd.a+gd.b<gs.a+gs.b;}
 
int main()
{
    n=read();rp(i,1,n)nod[i]=(node){read(),read()};m=read();
    sort(nod+1,nod+1+n);memset(f,-1,sizeof(f));f[0]=0;rp(i,1,n)f[0]+=nod[i].a;
    rp(i,1,n){my(j,as,0)if(f[j]+nod[i].b>=m)f[j+1]=max(f[j+1],f[j]-nod[i].a);if(f[as+1]>=0)++as;}
    printf("%d\n",as);
    return 0; 
}
放个代码QAQ

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值