zoukankan      html  css  js  c++  java
  • 百练 2757 最长上升子序列

    果然,动态规划的无后效性是和阶段的划分有关的。

    受前面的影响,涉及到n个元素的这种题目,我第一想法就是找前k个元素的最优解。

    但课件里面说了,这是不满足无后效性的:

    “求序列的前n个元素的最长上升子序列的长度”是个
    子问题,但这样分解子问题,不具有“无后效性”
    假设F(n) = x,但可能有多个序列满足F(n) = x。有的
    序列的最后一个元素比 an+1小,则加上an+1就能形成更长上
    升子序列;有的序列最后一个元素不比an+1小……以后的事
    情受如何达到状态n的影响,不符合“无后效性”

    确定了阶段的划分,状态转移方程还是很好理解的,代码也十分容易实现。

    描述

    一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1a2, ..., aN),我们可以得到一些上升的子序列(ai1ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8).

    你的任务,就是对于给定的序列,求出最长上升子序列的长度。

    输入

    输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。

    输出

    最长上升子序列的长度。

     两种代码实现,“人人为我,我为人人”,这八个字还是很形象的。

    人人为我:

    状态i的值Fi由若干个值已知的状态值Fk,Fm,..Fy推出,如求和,取最大值……

     1 //#define LOCAL
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 1010;
     9 int dp[maxn];
    10 int a[maxn];
    11 
    12 int main(void)
    13 {
    14     #ifdef LOCAL
    15         freopen("2757in.txt", "r", stdin);
    16     #endif
    17 
    18     int i, n, j;
    19     memset(dp, 0, sizeof(dp));
    20     dp[1] = 1;
    21     cin >> n;
    22     
    23     for(i = 1; i <= n; ++i)
    24     {
    25         scanf("%d", &a[i]);
    26         dp[i] = 1;    
    27     }
    28 
    29     for(i = 2; i <= n; ++i)
    30         for(j = 1; j < i; ++j)
    31         {
    32             if(a[j] < a[i])
    33             {
    34                 dp[i] = max(dp[i], dp[j]+1);
    35             }
    36         }
    37 
    38     int ans = 0;
    39     for(i = 1; i <= n; ++i)
    40         ans = max(ans, dp[i]);
    41     printf("%d
    ", ans);
    42     
    43     return 0;
    44 }
    代码君

    我为人人:

    状态i的值Fi在被更新(不一定是最终求出)的时候,依据Fi去更新(不一定是最终求出)和状态i相关的其他一些状态的值Fk,Fm,..Fy

     1 //#define LOCAL
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 1010;
     9 int dp[maxn];
    10 int a[maxn];
    11 
    12 int main(void)
    13 {
    14     #ifdef LOCAL
    15         freopen("2757in.txt", "r", stdin);
    16     #endif
    17 
    18     int i, j, n;
    19     scanf("%d", &n);
    20     for(i = 1; i <= n; ++i)
    21     {
    22         scanf("%d", &a[i]);
    23         dp[i] = 1;
    24     }
    25 
    26     for(i = 1; i < n; ++i)
    27         for(j = i+1; j <= n; ++j)
    28         {
    29             if(a[j] > a[i])
    30             {
    31                 dp[j] = max(dp[j], dp[i]+1);
    32             }
    33         }
    34 
    35     int ans = dp[1];
    36     for(i = 1; i <= n; ++i)
    37         ans = max(ans, dp[i]);
    38     printf("%d
    ", ans);
    39 
    40     return 0;
    41 }
    代码君
  • 相关阅读:
    20162304 2017-2018-1 《程序设计与数据结构》第十周学习总结
    20162304 2017-2018-1 《程序设计与数据结构》第九周学习总结
    20162304 2017-2018-1 《程序设计与数据结构》第八周学习总结
    20162302 2017-2018-1《程序设计与数据结构》课程总结
    20162302 实验五《数据结构综合应用》实验报告
    20162302 实验四《图的实现与应用》实验报告
    20162302 《程序设计与数据结构》第十一周学习总结
    20162302 《程序设计与数据结构》第十周学习总结
    20162302 实验三《查找与排序》实验报告
    20162302 《程序设计与数据结构》第九周学习总结
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3851568.html
Copyright © 2011-2022 走看看