poj 1065 Wooden Sticks(贪心算法)

来源:互联网 发布:手机棋牌游戏辅助软件 编辑:程序博客网 时间:2024/05/16 10:03

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

213

 

思路:按木棍的长度从小到大排序,当木棍长度相等时,按重量小到大排序。然后依次选择比当前长度大并且重量也大的木棍(已经对木棍进行排序,每次选择都是对后面影响最小的),对选过的木棍进行标记,这些木棒就是被处理的木棒。一轮之后,启动时间+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 stickscin>>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;}


 

 

 

原创粉丝点击