hdu 1423 最长公共递增子序列
这题一开始把我给坑了,我还没知道LCIS的算法,然后就慢慢搞吧,幸运的是还真写出来了,只不过麻烦了一点。
我是将该题转换为多条线段相交,然后找出最多多少条不相交,并且其数值死递增的。
代码如下:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int dp[510][510]; int list1[510],list2[510]; struct Edge{ int val,vex[510]; int pos; }p[510]; void init() { int i,j; for(i=0;i<=500;i++) for(j=0;j<=500;j++) dp[i][j]=1; for(i=0;i<=500;i++) p[i].pos=0; } int main() { int t,n,m,i,j,k,r,f; scanf("%d",&t); while(t--) { init(); scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&list1[i]); scanf("%d",&m); for(i=1;i<=m;i++) scanf("%d",&list2[i]); int f=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(list1[i]==list2[j]) { p[i].val=list1[i]; p[i].vex[p[i].pos++]=j; f=1; } } } /*for(i=1;i<=n;i++) { cout<<" ** "<<p[i].val<<" ** :"; for(j=0;j<p[i].pos;j++) cout<<p[i].vex[j]<<" "; cout<<endl; }*/ int Max=0; if(f) Max=1; for(i=1;i<=n;i++) { for(j=1;j<i;j++) { if(p[i].val>p[j].val) { //cout<<"ok"<<endl; //cout<<p[i].val<<" "<<p[j].val<<endl; for(k=0;k<p[i].pos;k++) { for(r=0;r<p[j].pos;r++) { if(p[i].vex[k]>p[j].vex[r]) dp[i][p[i].vex[k]]=max(dp[i][p[i].vex[k]],dp[j][p[j].vex[r]]+1); if(dp[i][p[i].vex[k]]>Max) { Max=dp[i][p[i].vex[k]]; //cout<<Max<<endl; } } } } } } printf("%d\n",Max); if(t) printf("\n"); } return 0; }
正解的代码有如下两种版本,一种是一维数组,一种二维。思想是一样的。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int dp[510][510],a[510],b[510]; int LCIS(int n,int m) { int i,j,k,temp; int ans=0; memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { temp=0; for(j=1;j<=m;j++) { dp[i][j]=dp[i-1][j]; if(a[i]==b[j]) dp[i][j]=temp+1; if(a[i]>b[j]&&dp[i-1][j]>temp) temp=dp[i-1][j]; if(ans<dp[i][j]) ans=dp[i][j]; } } return ans; } int main() { int t,n,m,i,j; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(i=1;i<=m;i++) scanf("%d",&b[i]); printf("%d\n",LCIS(n,m)); if(t) printf("\n"); } }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int f[510],a[510],b[510]; int LCIS(int n,int m) { int i,j,k; memset(f,0,sizeof(f)); for(i=1;i<=n;i++) { k=0; for(j=1;j<=m;j++) { if(a[i]==b[j]) f[j]=max(f[j],k+1); if(a[i]>b[j]&&f[j]>k) k=f[j]; //cout<<k<<endl; } } int ans=0; for(i=0;i<=m;i++) ans=max(ans,f[i]); return ans; } int main() { int t,n,m,i,j; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(i=1;i<=m;i++) scanf("%d",&b[i]); printf("%d\n",LCIS(n,m)); if(t) printf("\n"); } }