您的位置:首页 > 其它

codeforces 4D Mysterious Present -- 动态规划

2014-04-29 23:34 796 查看
D. Mysterious Present

time limit per test
2 seconds

memory limit per test
64 megabytes

input
standard input

output
standard output

Peter decided to wish happy birthday to his friend from Australia and send him a card. To make his present more mysterious, he decided to make a chain. Chain here is such a sequence of envelopes A = {a1,  a2,  ...,  an},
where the width and the height of the i-th envelope is strictly higher than the width and the height of the (i  -  1)-th
envelope respectively. Chain size is the number of envelopes in the chain.

Peter wants to make the chain of the maximum size from the envelopes he has, the chain should be such, that he'll be able to put a card into it. The card fits into the chain if its width and height is lower than the width and the height of the smallest envelope
in the chain respectively. It's forbidden to turn the card and the envelopes.

Peter has very many envelopes and very little time, this hard task is entrusted to you.

Input

The first line contains integers n, w, h (1  ≤ n ≤ 5000, 1 ≤ w,  h  ≤ 106)
— amount of envelopes Peter has, the card width and height respectively. Then there follow n lines, each of them contains two integer numbers wi and hi —
width and height of the i-th envelope (1 ≤ wi,  hi ≤ 106).

Output

In the first line print the maximum chain size. In the second line print the numbers of the envelopes (separated by space), forming the required chain, starting with the number of the smallest envelope. Remember, please, that the card should fit into the smallest
envelope. If the chain of maximum size is not unique, print any of the answers.

If the card does not fit into any of the envelopes, print number 0 in the single line.

Sample test(s)

input
2 1 1
2 2
2 2


output
1
1


input
3 3 3
5 4
12 11
9 8


output
3
1 3 2


题目大意是,输入一个卡片和一系列的信封,它们有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: