uva 111 History Grading

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;
}
原文地址:https://www.cnblogs.com/scau20110726/p/2824252.html