题型: 贪心
思路: 由于一个盒子在考虑放入另一个盒子之前,要考虑两个因素,宽和高,如果我们能够消除一个因素,就在一维的条件下考虑会简单些。怎么才能降低维数呢。因为只有w小于另一个时才能才能考虑是否能放,所以我们就把w从小到大排序,这样大体盒子的先后顺序就有了,我们在比较的时候就不需要考虑宽了,因为只有后边的盒子才能容纳前边的盒子
先不考虑w和h相同的情况,排好序后,从第一个盒子开始遍历,第一个盒子不能容纳其他任何的盒子(宽最小),所以直接做为一个桶了。然后第二个,看他能不能容纳第一个,只需考虑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就没有办法4和5了,就单独一个桶了,最后是四个桶,看来不够优啊。
贪心就是找一个刚好能容的情况。
以上分享转自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; }