Greatest Common Increasing Subsequence poj 2127

来源:互联网 发布:如何设计淘宝海报 编辑:程序博客网 时间:2024/06/05 18:46

这道题目折磨了我两天,折磨的地方不是转移方程,而是为什么用一维的存储路径不可以。

明显的动态规划题目,糅合了LCS,LIS,构成了LCIS。

对于a[],b[],dp[i][j]定义为以a[i.....i],b[1......j]中,以b[j]为结尾的最长上升序列。

dp[j] = dp[k] + 1, if seq1[i] = seq2[j], 1 <= k < j

下面是最简版本,只能求出最长的有多少,而这道题目要你得出最长是什么。

int LCIS(){      int i, j;      int Max;      memset(dp, 0, sizeof(dp));      for (i = 1; i <= len1; ++i){          Max = 0;          for (j = 1; j <= len2; ++j){              if (seq1[i] > seq2[j] && Max < dp[j])                  Max = dp[j];              if (seq1[i] == seq2[j])                  dp[j] = Max + 1;          }      }      Max = 0;      for (i = 1; i <= len2; ++i){          if (Max < dp[i])              Max = dp[i];      }      return Max;  }  

这道题目起初认为使用一维记录路径,类似LIS那样有个Path即可。但是后来发现事情并非如此,因为

------i1--------i2--------i3------

---------j1---------j2-------j3-----

j2的决策点可能会因为i3 的到来而改变。

这个状态只能说b[j]结尾的最优而并不一定满足公共上升的条件。即后来的点可能会改变答案中某点的前驱改变

eg:

6
3 6 9 12 4 6
5
3 4 6 9 12

比如这个序列,i= 3 6 9 12 的时候 dp=1 0 2 3 4
但这个时候4的到来改变了 使之成为 1 1 2 3 4
这时候6再来,则改变了6原本位置上的前驱。dp成为 1 1 3 3 4
这个dp的定义,可能会改变前驱,因为dp[j]只是以J为结尾而并没有这个限制条件

AC:

#include <stdio.h>#include <string.h>#define MAXN 10+1000int dp[MAXN][MAXN];int a[MAXN],b[MAXN],c[MAXN];int N,M,T;int R;void LCIS(){int i,j,k;int maxnum;memset(dp,0,sizeof(dp));for(i=0;i<N;i++){maxnum=0;k=-1;if(i!=0)memcpy(&dp[i],&dp[i-1],sizeof(dp[0]));for(j=0;j<M;j++){if(a[i]>b[j] && maxnum<dp[i][j])maxnum=maxnum>dp[i][j]?maxnum:dp[i][j],k=j;if(a[i]==b[j])dp[i][j]=maxnum+1;}}for(maxnum=i=0;i<M;i++)if(maxnum<dp[N-1][i]) maxnum=dp[N-1][i],k=i;printf("%d\n",maxnum);if(maxnum==0){printf("\n");return;}i=N-1,j=k,k=0;R=0;while(1){while(i>=0 && a[i]!=b[j])i--;if(i<0)break;c[R++]=b[j];if(dp[i][j]==1)break;k=j-1;while(k>=0){if(b[k]<b[j] && dp[i][j]-1==dp[i][k])break;k--;}j=k;if(j<0)break;}for(i=R-1;i>=0;i--)if(i==0)printf("%d",c[i]);else    printf("%d ",c[i]);printf("\n");}int main(){   while(scanf("%d",&N)!=EOF){int i;for(i=0;i<N;i++)scanf("%d",a+i);scanf("%d",&M);for(i=0;i<M;i++)scanf("%d",b+i);LCIS();}return 0;}/*63 6 9 12 4 653 4 6 9 1291 4 7 5 6 2 3 4 5 91 4 7 5 6 2 3 4 5 41 2 3 451 3 4 2 3*/


0 0
原创粉丝点击