hdu 1677 pku3636

题型: 贪心

思路: 由于一个盒子在考虑放入另一个盒子之前,要考虑两个因素,宽和高,如果我们能够消除一个因素,就在一维的条件下考虑会简单些。怎么才能降低维数呢。因为只有w小于另一个时才能才能考虑是否能放,所以我们就把w从小到大排序,这样大体盒子的先后顺序就有了,我们在比较的时候就不需要考虑宽了,因为只有后边的盒子才能容纳前边的盒子

先不考虑wh相同的情况,排好序后,从第一个盒子开始遍历,第一个盒子不能容纳其他任何的盒子(宽最小),所以直接做为一个桶了。然后第二个,看他能不能容纳第一个,只需考虑h满足要求与否。然后第三个,问题来了,它既能容纳第一个,又能容纳第二个,选择哪一个,贪心就在这,它能刚好容纳谁,就容纳它,加入没有容纳那个刚好放进的,而是把一个小的多的容纳了,那么这个刚好的可能在以后就没法放进任何桶里了。

举个例子:

1 8 2 4 3 3 4 5 5 4

看这个例子:h序列是: 8 4 3 5 4

现在开始实施装桶。

8单独做为一个桶。 桶的序列是:8

4 没有办法容纳8,所以也单独作为一个桶   桶的序列是:8 4

3 没有办法容纳前边的两个,所以也单独作为一个桶 桶的序列是:8 4   3

5 可以容纳 4 3,最优的情况是容纳4          桶的序列是:8 5 3

4 可以容纳 3   桶的序列是:8 5 4

假如5容纳了3 ,桶的序列是:8 4 5

4就没有办法45了,就单独一个桶了,最后是四个桶,看来不够优啊。

贪心就是找一个刚好能容的情况。

以上分享转自http://hi.baidu.com/woaijiangshuan/blog/item/801c56093190183a6059f3b5.html

下面是代码

#include<iostream>
#include<algorithm>
using namespace std;
struct Node
{
	int h,w;
 bool operator<(Node a){
              if(a.w==w)
                     return h>a.h;
              return w<a.w;
       }
}ele[20005];
int a[20005];
int main()
{
	int cas,n;
	cin>>cas;
	while(cas--)
	{
		cin>>n;
		for(int i=0;i<n;i++)
			cin>>ele[i].w>>ele[i].h;
		sort(ele,ele+n);
		int q=0;
		for(int i=0;i<n;i++)
		{
			int l=0,r=q;
			while(l<r)
			{
				int m=(r+l)/2;
				if(a[m]>=ele[i].h)
					l=m+1;
				else r=m;
			}
			a[l]=ele[i].h;//a[]保存每个桶的边界值
			q+=l==q;//假如,没有找到,就新加一个桶。
		}
		cout<<q<<endl;
	}
	return 0;
}
posted @ 2011-08-11 00:19  枕边梦  阅读(307)  评论(0编辑  收藏  举报