• 【HDU 1275 && HDU 1677】 两题类似,经典 DP。


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

    题目链接:

    1257

    解题思路:

        一开始一直纠结在求最小下降的次数(从大减少到最小的的为一次)。 想了很久才恍然大悟,这题可以转换成求最长非降子序列。贪心思想。

     1 http://acm.hdu.edu.cn/showproblem.php?pid=1257#include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <cstring>
     6 using namespace std;
     7 
     8 const int maxn=150000;
     9 int  max_len[maxn];
    10 int  f[maxn];
    11 
    12 int main()
    13 {
    14     int  n, flag;
    15     while(cin >> n)
    16     {
    17         for(int i=1; i<=n; i++)
    18             cin >> f[i];
    19         int  Max=-1;
    20         for(int i=1; i<=n; i++)
    21         {
    22             max_len[i]=1;
    23             for(int j=1; j<i; j++)
    24             {
    25                 if( f[j]<f[i] && max_len[j]+1>max_len[i])
    26                 {
    27                     max_len[i]=max_len[j]+1;
    28                 }
    29             }
    30             if(Max<max_len[i])
    31             {
    32                 Max=max_len[i];
    33             }
    34         }
    35         cout << Max <<endl;
    36     }
    37     return 0;
    38 }

    1677

    题目大意:给你n个宽为w,高为h的洋娃娃,小的洋娃娃能装到大的洋娃娃里面。问你尽可能装完后剩下的洋娃娃数。

    解题思路:

          这题和上一题思想类似,先排个序,注意排序的时候w从大到小排,当w相等时h从小到大排,这么排的原因是w或者h相同的不能被装下(后面的dp会让你清楚为什么这么排)。接下来如果和上题一样用直接用贪心做的话,TLE,囧。

         这题要换种做法,用dp。将排序后的h存入dp[0~n-1]中,再从0开始对这个序列进行遍历。定义一个max_len最长递增序列长度。如果第i个h大于前面存的,max_len加1,并存入dp[max_len]的最后一个。如果小于第j个(j属于(0~max_len-1)),则将第dp[i]替换第dp[j]。以此类推,动态的更新存储求得的max_len就是最大的了。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <cstring>
     6 using namespace std;
     7 
     8 const int maxn=20005;
     9 int  dp[maxn];
    10 
    11 struct node
    12 {
    13     int w, h;
    14 }f[maxn];
    15 
    16 bool cmp(node A, node B)
    17 {
    18     if(A.w!=B.w)
    19         return A.w>B.w;
    20     else
    21         return A.h<B.h;
    22 }
    23 
    24 int LIS(int n)
    25 {
    26     int max_len=0, i, j;
    27     for(i=0; i<n; i++)
    28     {
    29         for(j=0; j<max_len; j++)
    30           if(dp[i]<dp[j]) break;
    31         if(j==max_len) max_len++;
    32         dp[j]=dp[i];
    33     }
    34     return max_len;
    35 }
    36 
    37 int main()
    38 {
    39     int  T, n;
    40     cin >> T;
    41     while(T--)
    42     {
    43         cin >> n;
    44         for(int i=0; i<n; i++)
    45             scanf("%d%d",&f[i].w,&f[i].h);
    46         sort(f,f+n,cmp);
    47         memset(dp,0,sizeof(dp));
    48         for(int i=0; i<n; i++)
    49             dp[i]=f[i].h;
    50         cout << LIS(n) <<endl;
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    Solr简介
    儿童节快乐
    添加新的内容分类
    weka
    Junit测试样例
    Linux MySQL单实例源码编译安装5.5.32
    perconatoolkit 工具集安装
    Linux MySQL单实例源码编译安装5.6
    MySQL 开机自启动
    mysql5.6之前需要账号的安全加固
  • 原文地址:https://www.cnblogs.com/kane0526/p/2796685.html
Copyright © 2020-2023  润新知