博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 1423 Greatest Common Increasing Subsequence(DP 最长公共上升子序列)
阅读量:5249 次
发布时间:2019-06-14

本文共 2162 字,大约阅读时间需要 7 分钟。

Greatest Common Increasing Subsequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2081    Accepted Submission(s): 626


Problem Description
This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence.
 

Input
Each sequence is described with M - its length (1 <= M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence itself.
 

Output
output print L - the length of the greatest common increasing subsequence of both sequences.
 

Sample Input
 
1 5 1 4 2 5 -12 4 -12 1 2 4
 

Sample Output
 
2
 

Source
 

Recommend
lcy

思路:

能想到的最简单的方法就是对a的每一项和b的每一项进行匹配,当找到一个匹配的
时候,就往回找比它小的一个最长公共子列,如a[i]==b[j],就搜a[0,i-1]*b[0,j
-1]这个矩形里面比a[i]小的最长公共递增子列。简化的代码如下:

for(i=1;i<=l1;i++)

for(j=1;j<=l2;j++)
if (a[i-1]==b[j-1])
{
    max=0;
    for(i1=1;i1<i;i1++)
    for(j1=1;j1<j;j1++)
    if (a[i1-1]==b[j1-1] && a[i1-1]<a[i-1] && f[i1][j1]>max) max=f[i1][j1];
    f[i][j]=max+1;
}

0(n^4)

一次优化

for(i=1;i<=l1;i++)

for(j=1;j<=l2;j++)
{
    f[i][j]=a[i-1][j];
    if (a[i-1]==b[j-1])
    {
        max=0;
        for(k=1;k<j;k++)
        if (b[k-1]<b[j-1] && f[i][max]<f[i][k]) max=k;
/*  这里如果f[i][k]>0,因为b[k]<b[j],所以不可能是a[i-1]和b[k]匹配,所以只
可能是a[0,i-2]和其匹配,故符合公共递增子列的要求    */
        if (f[i][max]+1>f[i][j]) f[i][j]=f[i][max]+1; 
   }
}

0(n^3)

二次优化

  for(int i=1;i<=la;i++)

      { int k=0;
        for(int j=1;j<=lb;j++)
        {
          if(a[i]>b[j]&&f[i-1][j]>f[i-1][k])
          {k=j;
          }
          f[i][j]=max(f[i-1][j],f[i][j-1]);
            if(a[i]==b[j]&&f[i][j]<f[i-1][k]+1)
            {f[i][j]=f[i-1][k]+1;
            }
        }
      }

0(n^2)

#include
#include
#include
using namespace std;const int mm=555;int f[mm][mm];///前i个a与前j个b匹配的最优值int a[mm],b[mm],la,lb;int main(){ int cas; while(cin>>cas) { while(cas--) { cin>>la; for(int i=1;i<=la;i++)cin>>a[i]; cin>>lb; for(int i=1;i<=lb;i++)cin>>b[i]; memset(f,0,sizeof(f)); int ans=0; for(int i=1;i<=la;i++) { int k=0; for(int j=1;j<=lb;j++) { if(a[i]>b[j]&&f[i-1][j]>f[i-1][k])///扫描i行符合条件的最长子序列,用k记录 {k=j; } f[i][j]=max(f[i-1][j],f[i][j-1]);///更新f[i][j]值 if(a[i]==b[j]&&f[i][j]

转载于:https://www.cnblogs.com/nealgavin/archive/2013/02/03/3206167.html

你可能感兴趣的文章
HttpClient 教程 (五)
查看>>
vue和react的区别
查看>>
PHP文件包含漏洞利用
查看>>
document.documentElement和document.body区别介绍
查看>>
Cocos2d-x中Vector使用
查看>>
第十一次作业
查看>>
mybatis CRUD
查看>>
负载均衡策略
查看>>
Go 语言的基本数据类型
查看>>
数据库建立索引加快查询
查看>>
[codevs 2235]机票打折
查看>>
微信智能开放平台
查看>>
C# ArcgisEngine开发中,对一个图层进行过滤,只显示符合条件的要素
查看>>
ArcGIS Engine 中的绘制与编辑
查看>>
Oracle--通配符、Escape转义字符、模糊查询语句
查看>>
子网划分讲解及练习(一)
查看>>
Python 装饰器
查看>>
c# 文件笔记
查看>>
Vue 自定义指令
查看>>
帆软 控件内容 清除
查看>>