【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 }

 

你可能感兴趣的:(HDU)