题目大意是,输入一个卡片和一系列的信封,它们有w和h值。要求最后输出信封的编号,满足:信封按升序(w,h都是前者小于后者)排列,并且它们都小于卡片。
我们可以先将信封排一个序,就先w后h吧,这样,这个排序并不是题意的那种排序,但是,按题意得出的串在这个序中也是有序的。那么,一个较大的数,一定包含一个数,这个数比它小,同时,比这个数小的数最多。这就可以用动态规划,记录比每个数小的数目,以及它上一个数。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class Point{
public:
int id,w,h;
Point(int id, int w, int h){ this->id=id; this->w = w; this->h = h; }
Point(){}
bool operator <(const Point p) const{ return w == p.w ? h < p.h : w<p.w; }
bool totalLess(const Point p) const{ return w<p.w && h<p.h; }
};
vector<Point> envelops;
int main(){
int n,w,h;
int endi;
Point card;
vector<int> costv,hisv;
int cost,his;
int left;
#ifndef ONLINE_JUDGE
freopen("data","r",stdin);
#endif
cin>>n>>card.w>>card.h;
for(int i=1; i<=n; i++){
cin>>w>>h;
envelops.push_back(Point(i,w,h));
}
sort(envelops.begin(),envelops.end());
for(int i=0;i<envelops.size();i++){
card.totalLess(envelops[i]) ? cost = 1 : cost = 0;
his = -1;
if(cost>0)
for(int j=0; j<i; j++){
if( envelops[j].totalLess(envelops[i]) && costv[j]+1>cost ){
cost = costv[j]+1;
his = j;
}
}
costv.push_back(cost);
hisv.push_back(his);
}
endi = max_element(costv.begin(),costv.end())-costv.begin();
cout<< costv[endi] << endl;
#ifndef ONLINE_JUDGE
cout<<"costv: "<<endl;
for(int i=0; i<costv.size(); i++){
cout<<costv[i];
}
cout<<endl;
cout<<"hisv: "<<endl;
for(int i=0; i<hisv.size(); i++){
cout<<hisv[i];
}
cout<<endl;
cout<< "\tendi: " << endi <<endl;
#endif
if( 0 != costv[endi] ){
vector<int> answerv;
answerv.push_back(envelops[endi].id);
int pre = hisv[endi];
while( -1 != pre ){
answerv.push_back(envelops[pre].id);
pre = hisv[pre];
}
for(int i=answerv.size()-1; i>=0; i--){
cout<<answerv[i]<<" ";
}
cout<<endl;
}
return 0;
}