zoukankan      html  css  js  c++  java
  • 动态规划:LIS

    题目中的严格二字,表示的意思是不允许≥或者是≤的情况出现,只允许>的情况以及<的情况

    经典问题是NOIP合唱队形,在这个题目中,既求了最长上升子序列,也求了最长下降子序列

    其最终的结果由两个子序列的结果共同得来

    我们给出实现方法:

    //最长上升子序列 
    

        for(int i=1;i<=n;i++)
        for(int j=i-1;j>=0;j--)
        if(a[j]<a[i])
          f1[i]=max(f1[i],f1[j]+1);

    //最长下降子序列 

        for(int i=n;i>=1;i--)
        for(int j=i+1;j<=n+1;j++)
        if(a[j]<a[i])
          f2[i]=max(f2[i],f2[j]+1);

    以最长上升子序列为例,其转移方程为:f(i)=max(f(i),f(j)+1),并且当a[i]>a[j]时进行转移

    在实现的时候,一定要控制好下标,以及边界处理,以上代码的边界处理是没有问题的

    下面给出合唱队形这道题的代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=105;
     5 int n;
     6 int ans;
     7 int a[maxn];
     8 int f1[maxn],f2[maxn];
     9 int main()
    10 {
    11     scanf("%d",&n);
    12     for(int i=1;i<=n;i++)
    13         scanf("%d",&a[i]);
    14     for(int i=1;i<=n;i++)
    15     for(int j=i-1;j>=0;j--)
    16     if(a[j]<a[i])
    17         f1[i]=max(f1[i],f1[j]+1);
    18     for(int i=n;i>=1;i--)
    19     for(int j=i+1;j<=n+1;j++)
    20     if(a[j]<a[i])
    21         f2[i]=max(f2[i],f2[j]+1);
    22     for(int i=1;i<=n;i++)
    23         ans=max(ans,f1[i]+f2[i]);
    24     ans=n-ans+1;
    25     printf("%d
    ",ans);
    26     return 0;
    27 }
  • 相关阅读:
    HDU 1022 Train Problem I
    HDU 1702 ACboy needs your help again!
    HDU 1294 Rooted Trees Problem
    HDU 1027 Ignatius and the Princess II
    HDU 3398 String
    HDU 1709 The Balance
    HDU 2152 Fruit
    HDU 1398 Square Coins
    HDU 3571 N-dimensional Sphere
    HDU 2451 Simple Addition Expression
  • 原文地址:https://www.cnblogs.com/aininot260/p/9305962.html
Copyright © 2011-2022 走看看