poj 1065 Wooden Sticks(贪心算法)

题目:来自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;
}


 

 

 

你可能感兴趣的:(poj 1065 Wooden Sticks(贪心算法))