hdoj1160 DP--LIS

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1160

思路:

又是一道LIS的应用题,先预处理,按照w从小到大排列,那么原问题就转变成求该排列的LIS,但需要定义元素id记录该数据在原来排列中的位置,并定义pre元素记录某数据在LIS中的上一个数据,因为要输出LIS的结点序列,使用LIS的O(nlogn)解法并不方便,加上数据不大(1000),因此使用LIS的O(n^2)解法,用dp[i]表示以i结尾的上升子序列的最大长度,注意要将dp初始化为1,结果逆向输出即可。详见代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct node{
 5     int w,s,id,pre;
 6     bool operator < (const node& other) const{
 7         return w<other.w;
 8     }
 9 }a[1005];
10 
11 int w,s,k=1,n,res,dp[1005];
12 
13 void print(int p){
14     if(p){
15         print(a[p].pre);
16         printf("%d\n",a[p].id);
17     }
18 }
19 
20 int main(){
21     while(scanf("%d%d",&w,&s)!=EOF){
22         a[k].w=w,a[k].s=s,a[k].id=k,a[k].pre=0;
23         dp[k]=1;
24         k++;
25     }
26     sort(a+1,a+k);
27     n=0;
28     for(int i=1;i<k;i++){
29         for(int j=1;j<i;j++)
30             if(a[j].w<a[i].w&&a[j].s>a[i].s)
31                 if(dp[j]+1>dp[i])
32                     dp[i]=dp[j]+1,a[i].pre=j;
33         if(dp[i]>n) n=dp[i],res=i;
34     }
35     printf("%d\n",n);
36     print(res);
37     return 0;
38 }

 

posted @ 2019-02-19 21:38  Frank__Chen  阅读(189)  评论(0编辑  收藏  举报