题目链接: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 ",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); 36 print(res); 37 return 0; 38 }