UVA 111 - History Grading

本文详细解析了一道动态规划(DP)题的核心概念,即如何在给定的时间序列中找到最长的公共子序列,并提供了具体的代码实现。通过将输入数据进行转化,将事项与其发生时间对应起来,再运用DP算法解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道dp题主要理解好题意:题中给的是按事项顺序的时间排列,而你要求的最长公共子序列是按时间顺序的事项排列,所以给你的排列要转化一下:例如:

10
3 1 2 4 9 5 10 6 8 7//意思是:1事项在第三个时间位置发生,2事项在第一个时间发生以此类推:转化为:2 3 1 4 6 8 10 9 5 7
1 2 3 4 5 6 7 8 9 10
4 7 2 3 10 6 9 1 5 8
3 1 2 4 9 5 10 6 8 7
2 10 1 3 8 4 9 5 7 6
代码如下:
#include<stdio.h>
#include<string.h>
#define MAXN 20+5
int n, T[MAXN],T1[MAXN], a[MAXN],a1[MAXN], f[MAXN][MAXN];
int compa, ord;
void change()
{
for(int i = 1; i <= n; i ++)
{
T1[T[i]] = i;
a1[a[i]] = i;
}
}
void dp()
{
ord = 0;
memset(f,0,sizeof(f));//printf("3\n");
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
{
if(T1[i] == a1[j]) f[i][j] = f[i-1][j-1] + 1;
else
{
if(f[i-1][j] < f[i][j-1]) f[i][j] = f[i][j-1];
else f[i][j] = f[i-1][j];
}
if(f[i][j] > ord) ord = f[i][j];
}
//ord = f[n][n];printf("ord=%d\n",ord);
}
void comp()
{
compa = 0;
for(int i = 1; i <= n; i ++)
if(a1[i] == T1[i]) compa ++;//printf("compa=%d\n",compa);
}
void input()
{
while(scanf("%d", &n) == 1)
{
memset(T,0,sizeof(T));
memset(a,0,sizeof(a));
for(int i = 1; i <= n; i ++)
scanf("%d",&T[i]);
for(;;)
{
for(int i = 1; i <= n; i ++)
if(scanf("%d",&a[i]) == EOF) return;
change();
comp();//printf("1\n");
dp();
if(compa > ord) printf("%d\n",compa);
else printf("%d\n",ord);
}
}
}
int main()
{
input();
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值