您的位置:首页 > 其它

【BZOJ3174】【Tjoi2013】拯救小矮人 贪心+动规。

2015-01-19 20:16 309 查看
转载请注明出处~~~thx~/article/2544935.html

呃、

就是先贪心排序一下,然后做动规。

题解:

首先我们考虑两个人之间的先后离开顺序:

肯定我们希望逃生能力(权值a+权值b)强的人后跑,因为这样更可能多跑

(这里不妨考虑:我们希望整个塔的逃生能力更强,而塔的逃生能力就是所有人的身高+max{手长})。

然后这样我们可以按照逃跑顺序排个序,方便接下来的动规。

(不要太较真~~我也不是特别“有理有据”,只是感性地YY了一下这个证明)

逃跑顺序出来以后,我们设f[i]为所有人中跑出去i个人后塔的最高高度(不算max{手长})

这里再感性地想一下,就是在同等的人逃出去的前提下,如果我们还想人逃出去,那么这个总的逃生能力肯定是要尽量大的,而逃跑顺序已经有上述的贪心来保证,那么要提高将要逃跑的这个人的逃跑能力,方法就是在底下垫人,肯定就是越高越好~~

差不多了,觉得不够的可以自己再随便查查网上题解,还是有那么两篇的。~·~。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 101000
using namespace std;
struct KSD
{
	int x,y;
	bool operator < (const KSD &a)const{return x+y<a.x+a.y;}
}ksd
;
int n,m,ans,f
;
int main()
{
	int i,j;
	scanf("%d",&n);
	memset(f,-1,sizeof(f)),f[0]=0;
	for(i=1;i<=n;i++)scanf("%d%d",&ksd[i].x,&ksd[i].y),f[0]+=ksd[i].x;
	sort(ksd+1,ksd+n+1);
	scanf("%d",&m);
	for(i=1;i<=n;i++)
	{
		for(j=ans;j>=0;j--)
		{
			if(ksd[i].y+f[j]>=m)f[j+1]=max(f[j+1],f[j]-ksd[i].x);
			if(f[ans+1]>=0)ans++;
		}
	}
	printf("%d\n",ans);
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: