题目:来自http://poj.org/problem?id=1065
描述:有一些木棍,每个有长度和重量,要求把这些木棍排成若干两个属性值均不下降的序列。问至少要分为多少个序列。且要保证排出来的子序列数最少。
例如: ( 9 , 4 ) ,( 2 , 5 ) ,( 1 , 2 ) ,( 5 , 3 ),( 4 , 1 )可以排成这样
( 4 , 1 ) , ( 5 , 3 ) , ( 9 , 4 ) , ( 1 , 2 ) , ( 2 , 5 ) .
其中:(4,1)<=(5,3)<=(9,4)为不降序列,(4,1)<(5,3)由于4<5&&1<3
(1,2)<(2,5)为不降序列
即最少的不降子序列为2,输出2.
样例:
3
5
4 9 5 2 2 1 3 5 1 4
3
2 2 1 1 2 2
3
1 3 2 2 3 1
Sample Output
2
1
3
思路:按木棍的长度从小到大排序,当木棍长度相等时,按重量小到大排序。然后依次选择比当前长度大并且重量也大的木棍(已经对木棍进行排序,每次选择都是对后面影响最小的),对选过的木棍进行标记,这些木棒就是被处理的木棒。一轮之后,启动时间+1,再对剩下的木棍进行选择,即可得到最优解。
代码:
#include <iostream>
#include<algorithm>
using namespace std;
struct stick{
int length,weight;
bool flag;
friend istream& operator>>(istream& in,stick& s){
in>>s.weight>>s.length;
s.flag = false;
return in;
}
};
class comp{
public:
bool operator()(const stick& s1,const stick& s2)
{
if(s1.length==s2.length)return s1.weight<s2.weight;
else return s1.length<s2.length;
}
};
class WoodenSticks{
public:
WoodenSticks(int cases){
this->cases = cases;
}
void solution()
{
int i,j,k;
for(i=0;i<cases;i++){
int n;//n sticks
cin>>n;
stick* tmp = new stick[n];
int count = 0;
for(j=0;j<n;j++)
cin>>tmp[j];
sort(tmp,tmp+n,comp());
for(j=0;j<n;j++){
if(!tmp[j].flag){
count++;
tmp[j].flag = true;
int t = j;
if(j!=n-1){//最后一个棒,就不要查找了
for(k = j+1;k<n;k++){
if(tmp[k].weight>=tmp[t].weight&&!tmp[k].flag){
tmp[k].flag = true;
t = k;
}
}
}
}
}
delete[] tmp;
cout<<count<<endl;
}
}
private:
int cases;
};
int main()
{
int cases;
cin>>cases;
WoodenSticks poj1060(cases);
poj1060.solution();
system("pause");
return 0;
}