HDU-1160 FatMouse's Speed

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

题意:很多老鼠,每个老鼠有w(重量)和s(速度)两个属性,要求选一些老鼠,使他们的w严格递增且s严格递减,输出个数和老鼠的标号

思路:按照w升序排序,再求s的最长上升子序列(LIS),不过要注意的是本题还要求记录路径,为了方便,我用的是O(n^2)的路径存储算法我不会nlogn的,这里贴出nlogn别人的算法←点这里。pre[i]是记录该节点的前面是谁,更新dp[i]的时候顺手更新pre[i]就好啦,不过跑完一个dp[i]后记得更新所有dp[i]中最大的那个,也就是max_dp

代码:

 1 #include<bits/stdc++.h>
 2 #define inf 0x3f3f3f3f
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 typedef long double ld;
 7 
 8 const int M = int(1e5)*2 + 5;
 9 const int mod = 10056;
10 
11 inline int lowbit(int x) {
12     return x & (-x);
13 }
14 
15 struct node{
16     int w,s,ind;
17 };
18 node a[M];
19 bool cmp(node a,node b){
20     return a.s==b.s?a.w<b.s:a.s>b.s;
21 }
22 
23 int dp[M];
24 int pre[M];
25 int main(){
26     int k=0;
27     while(~scanf("%d%d",&a[k].w,&a[k].s)){
28         a[k].ind=k;
29         dp[k]=1;
30         pre[k]=-1;
31         k++;
32     }
33 
34     sort(a,a+k,cmp);
35     // for(int x=0;x<=k;x++) cout<<a[x].w<<" "<<a[x].s<<endl;
36 
37     int max_dp=0,max_i;
38     for(int i=0;i<k;i++){
39         for(int j=0;j<i;j++){
40             if(a[j].w<a[i].w && a[j].s>a[i].s){
41                 if(dp[i]<dp[j]+1){
42                     dp[i]=dp[j]+1;
43                     pre[i]=j;
44                 }
45             }
46         }
47         if(max_dp<dp[i]){
48             max_dp=dp[i];
49             max_i=i;
50         }
51     }
52 
53     cout<<max_dp<<endl;
54 
55     stack<int> st;
56     st.push(a[max_i].ind);
57     max_i=pre[max_i];
58     while(max_i!=-1){
59         st.push(a[max_i].ind);
60         max_i=pre[max_i];
61     }
62 
63     while(!st.empty()){
64         cout<<st.top()+1<<endl;
65         st.pop();
66     }
67     return 0;
68 }

备注:是不是很简单

原文地址:https://www.cnblogs.com/harutomimori/p/11287835.html