zoukankan      html  css  js  c++  java
  • ZOJ 2432 Greatest Common Increasing Subsequence(最长公共上升子序列+路径打印)

    Greatest Common Increasing Subsequence

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1432

    题目大意:给出两串数字,求他们的最长公共上升子序列(LCIS),并且打印出来。

    Sample Input

    1

    5
    1 4 2 5 -12
    4
    -12 1 2 4

    Sample Output

    2
    1 4

    分析:神奇就神奇在是LIS与LCS的组合

    令dp[i][j]表示A串的前i个,与B串的前j个,并以B[j]为结尾的LCIS 的长度.

    状态转移方程:

      f(A[i]==B[j])   dp[i][j]=max(dp[i-1][k])+1;  ( 1 <= k < j )

      else   dp[i][j]=dp[i-1][j];

    然后选择循环顺序,就可以将算法的复杂度降为n*n.

    代码如下:

     1 /*这个代码结果虽然对,跟样例的输出都不一样,而且两个输出数据之间有空行都没有实现,却能AC,有点匪夷所思*/
     2 # include<stdio.h>
     3 # include<string.h>
     4 #define MAX 550
     5 
     6 struct node{
     7     int x,y;
     8 }path[MAX][MAX];
     9 
    10 int dp[MAX][MAX];
    11 int s[MAX],t[MAX];
    12 
    13 int main(){
    14     int T,i,j;
    15     scanf("%d",&T);
    16     while(T--)
    17     {
    18         memset(path,0,sizeof(path));
    19         int n,m;
    20         scanf("%d",&n);
    21         for(i=1; i<=n; i++)
    22             scanf("%d",&s[i]);
    23         scanf("%d",&m);
    24         for(i=1; i<=m; i++)
    25             scanf("%d",&t[i]);
    26         memset(dp,0,sizeof(dp));
    27         int max = 0;
    28         for(i=1; i<=n; i++)
    29         {
    30             max = 0;
    31             int tx = 0,ty = 0;
    32             for(j=1; j<=m; j++)
    33             {
    34                 dp[i][j] = dp[i-1][j];
    35                 path[i][j].x = i-1;
    36                 path[i][j].y = j;
    37                 if( s[i] > t[j] && max < dp[i-1][j])
    38                 {
    39                     max = dp[i-1][j];
    40                     tx = i-1;
    41                     ty = j;
    42                 }
    43                 if( s[i] == t[j] )
    44                 {
    45                     dp[i][j] = max+1;
    46                     path[i][j].x = tx;
    47                     path[i][j].y = ty;
    48                 }
    49             }
    50         }
    51         max = -1;
    52         int id;
    53         for(i=1; i<=m; i++) 
    54             if(dp[n][i]>max) 
    55             {
    56                 max = dp[n][i];
    57                 id = i;
    58             }
    59             int save[MAX];
    60             int cnt=0;
    61             int tx,ty;
    62             tx=n; ty=id;
    63             while(dp[tx][ty] != 0 ) 
    64             {
    65                 int tmpx,tmpy;
    66                 tmpx = path[tx][ty].x;
    67                 tmpy = path[tx][ty].y;
    68                 if(dp[tx][ty] != dp[tmpx][tmpy])
    69                 {
    70                     save[cnt++]=t[ty];
    71                 }
    72                 tx = tmpx; ty = tmpy;
    73             }
    74             printf("%d
    ",max);
    75             for(i=cnt-1; i>=0; i--)
    76                 printf("%d ",save[i]);
    77             printf("
    ");
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    重读APUE(7)-link/unlink与mkdir/rmdir
    重读APUE(6)-umask
    社交系统中用户好友关系数据库设计
    修改Web项目的名称后,在TomCat中部署项目,项目的名称还是与原来相同的解决方案
    域名解析TTL是什么意思 TTL值设置为多少合适?
    mysql权限控制—新建用户允许其远程连接
    毕业设计技术方向(转载)
    统一资源定位符URL的组成
    开发中model,entity和pojo的区别
    要不要签三方协议
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/3263820.html
Copyright © 2011-2022 走看看