hdoj1160 DP--LIS

本文详细解析了HDU 1160题目,通过将原始问题转化为最长递增子序列(LIS)问题进行求解。文章介绍了如何通过预处理并使用O(n^2)的LIS算法找到最优解,同时记录了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 }

 

转载于:https://www.cnblogs.com/FrankChen831X/p/10403522.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值