hdu4512 最长公共上升子序列(LCIS)
关于最长公共上升子序列,dp[i][j]表示对应a[i],b[j]的以b[j]结尾的LCIS。
转移方程:
a[i]!=b[j]: dp[i][j]=dp[i-1][j]
a[i]==b[j]: dp[i][j]=max(dp[i-1][k])+1 1<=k<=j-1&&b[j]>b[k]
显然这是n3转移,只是该算法巧在加了一个maxx变量来控制max(dp[i-1][k])
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int dp[205][205]; 6 int a[1005],b[1005],x[1005]; 7 int LCIS(int n1,int n2) 8 { 9 int maxx,i,j; 10 memset(dp,0,sizeof(dp)); 11 for (i=1;i<=n1;i++) 12 { 13 maxx=0; 14 for (j=1;j<=n2;j++) 15 { 16 dp[i][j]=dp[i-1][j]; 17 if (b[j]<a[i]&&dp[i-1][j]>maxx) maxx=dp[i-1][j]; 18 if (b[j]==a[i]) dp[i][j]=maxx+1; 19 } 20 } 21 maxx=0; 22 for (i=1;i<=n2;i++) 23 if (dp[n1][i]>maxx) maxx=dp[n1][i]; 24 return maxx; 25 } 26 int main() 27 { 28 int T,i,j,n,maxy; 29 scanf("%d",&T); 30 while (T--) 31 { 32 scanf("%d",&n); 33 for (i=1;i<=n;i++) scanf("%d",&x[i]); 34 maxy=0; 35 for (i=1;i<=n;i++) 36 { 37 for (j=1;j<=i;j++) a[j]=x[j]; 38 for (j=n;j>=i;j--) b[n-j+1]=x[j]; 39 maxy=max(maxy,LCIS(i,n-i+1)*2-1); 40 maxy=max(maxy,LCIS(i,n-i)*2); 41 } 42 printf("%d\n",maxy); 43 } 44 }
空间可以优化成一维。。