HDU1160

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

题目大意:给出多个数据组(最多1000个),terminated by end of file,对于第 i 个数据组有两个数据:W[i] 和 S[i],要求找出一串数据组,在这串数据组中,W[i] 递增,对应的 S[I] 递减,要求数据串尽可能长。

解题思路:

  DP。用数组dp[i] 表示以第 i 组数据为结尾的最长长度。

  由于有每组有两个数据,我们可以一上来先对其中一种数据进行排序。我选择先把 W[i] 按从小到大排序,对于W[i] 相同的数据组,我们从大到小排序。这样一来,我们便可以少考虑一种数据,W[i] 已经能够保证合法,只要不是相等的情况。在外层循环中从头枚举各个数据组 i,计算dp[i] ,在内层循环中枚举第1至 i-1 组数据组 j,dp[i] = max( dp[j] + 1),当然,第 i 个数据组要满足W[i] < W[j] && S[i] > S[j]。

  用 pre[] 数组记录路径。

AC代码:

 1 #include <vector>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn=1000+10,inf=0x7ffffff;
 6 struct node{
 7     int W,S,ind;
 8 }n[maxn];
 9 int W[maxn],S[maxn],dp[maxn],pre[maxn],path[maxn];
10 bool cmp(const node &a,const node &b){
11     if(a.W<b.W) return 1;
12     else if(a.W==b.W&&a.S>b.S)  return 1;
13     return 0;
14 }
15 int main()
16 {
17     int num=1;
18     while(scanf("%d%d",&n[num].W,&n[num].S)==2){
19         pre[num]=0;
20         n[num].ind=num;
21         dp[num]=1;
22         num++;
23     }
24     sort(n+1,n+num,cmp);
25     int ans=0,aj;
26     for(int i=1;i<num;i++){
27         for(int j=1;j<i;j++){     //因为有了前面的排序,j必须小于i,不然之后的j不合法
28             if(n[j].W<n[i].W&&n[j].S>n[i].S&&dp[i]<dp[j]+1){
29                 dp[i]=dp[j]+1;
30                 pre[i]=j;
31                 if(dp[i]>ans){
32                     aj=i;
33                     ans=dp[i];
34                 }
35             }
36         }
37     }
38 
39     int t=0,ti=aj;
40     while(ti!=0){
41         path[t++]=ti;
42         ti=pre[ti];
43     }
44     printf("%d
",ans);
45     while(t>0){
46         t--;
47         printf("%d
",n[path[t]].ind);
48     }
49     return 0;
50 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/7289049.html