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 }
  • 相关阅读:
    Do you want a timeout?
    [整]常用的几种VS编程插件
    [转]Windows的窗口刷新机制
    [整][转]Invoke和BeginInvoke的使用
    [整]C#获得程序路径
    [转]Visual Studio 2010 单元测试目录
    飞秋的实现原理
    面向对象的七大原则
    [转]玩转Google开源C++单元测试框架Google Test系列
    [转]C#中的Monitor类
  • 原文地址:https://www.cnblogs.com/aininot260/p/9305962.html
Copyright © 2011-2022 走看看