dp入门题(LCS最长公共子序列)
先给出正确的序列,再给出多个学生写的序列,要求在正确和学生序列中找到LCS。但是要先转换即做一下映射
原本的序列是以事件为标准给出的,即以序列中的a[i]表示事件i发生的时间为a[i]。要转化为以时间为标准的,转化后a[i]表示时间i发生的事件为a[i]
然后以转化后的序列来求LCS
/* 先映射再用LIS模板求解 */ #include <cstdio> #include <cstring> #define N 25 int t[N]; //映射数组 int a[N]; int n; int max(int a ,int b) { return a>b?a:b; } void LCS() { int dp[N][N]; memset(dp,0,sizeof(dp)); for(int i=1; i<=n; i++) //t序列 for(int j=1; j<=n; j++) //a序列 { if(t[i]==a[j]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j] , dp[i][j-1]); } printf("%d\n",dp[n][n]); } int main() { scanf("%d",&n); memset(t,0,sizeof(t)); for(int i=1; i<=n; i++) //i是事件 { int tmp; //时间 scanf("%d",&tmp); t[tmp]=i; } /* printf("映射数组\n"); for(int i=1; i<=n; i++) printf("%d ",t[i]); printf("\n\n"); */ int tmp; while(scanf("%d",&tmp)!=EOF) { a[tmp]=1; for(int i=2; i<=n; i++) { scanf("%d",&tmp); a[tmp]=i; } /* for(int i=1; i<=n; i++) printf("%d ",a[i]); printf("\n"); */ LCS(); } return 0; }