uva131Is Bigger Smarter

题目:

       求最长的重量上升且iq下降的子序列

分析:

       其实就是最长上升子序列的变形,其实很简单,先按重量按照由小到大进行排序,

       然后就是LIS的事,打印路径的话,用数组path[]记录后面的位置,利用

       递归实现打印(具体参考算法导论)

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

#define X 1005

int dp[X],path[X];

struct node

{

       int iq,w,id;      //记录iq,重量以及未排序前的位置

}p[X];

int cmp(struct node a,struct node b)//按重量的非降序排列

{

       return a.w<b.w;

}

void print(int id)    //递归打印路径

{

       cout<<p[id].id<<endl;   //因为我是用数组记录后面的位置,所以先打印前面的id

       if(path[id]!=-1)

              print(path[id]);       //递归实现打印后面的位置

}

int main()

{

       freopen("sum.in","r",stdin);

       freopen("sum.out","w",stdout);

       int cnt = 0;

       while(scanf("%d%d",&p[cnt].w,&p[cnt].iq)!=EOF)

       {

              dp[cnt] = 1;    //初始化dp

              p[cnt].id = cnt+1;   //记录id

              cnt++;

       }

       sort(p,p+cnt,cmp);//对结构体进行排序

       int ans = 0;

       memset(path,-1,sizeof(path));

       for(int i=cnt-1;i>=0;i--)

              for(int j=i+1;j<cnt;j++)

                     if(p[i].iq>p[j].iq&&p[i].w<p[j].w)      //如果重量小于后面的并且iq大于后面的

                            if(dp[i]<dp[j]+1)

                            {

                                   path[i] = j;      //记录路径

                                   dp[i] = dp[j]+1;

                            }

       int id;

       for(int i=0;i<cnt;i++)

              if(ans<dp[i])

              {

                     ans = dp[i];

                     id = i;            //找出最早的id

              }

       cout<<ans<<endl;

       print(id);

       return 0;

}

原文地址:https://www.cnblogs.com/yejinru/p/2387862.html