LCS问题:动规方程:dp [i][j] = dp[i-1][j-1] +1 (numx[i] = numy[j]) || max{ dp[i-1] [j] , dp[i][j-1] } || 0 (i=0 || j =0) ;
注意此题题目的意思,有点绕人,看数据的时候感觉很奇怪,然后再仔细看题,才知道,输入的一系列数,对应位i上的数a[i]表示的是第i件事情发生的时间。
代码如下:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std ;
const int maxn = 25 ;
int n;
int numx[maxn] ;
int numy[maxn] ;
int dp[maxn][maxn] ;
int main()
{
//freopen("data.in" , "r" , stdin) ;
int i ;
int j ;
int x ;
cin>>n;
for(i = 1 ; i <= n ; i ++)
{
cin>>x ;
numx[x] = i ;
}
while(cin>>x)
{
numy[x] = 1 ;
for(j = 2 ; j <= n ; j ++)
{
cin>>x ;
numy[x] = j ;
}
memset(dp , 0 , sizeof(dp)) ;
for(i = 1 ; i <= n ; i ++)
{
for(j = 1 ; j <= n ; j ++)
{
if(numx[i]==numy[j])
dp[i][j] = dp[i-1][j-1] + 1 ;
else
dp[i][j] = dp[i-1][j] > dp[i][j-1] ? dp[i-1][j] : dp[i][j-1] ;
}
}
printf("%d\n" , dp[n][n]) ;
}
return 0 ;
}
我刚刚有重新用记忆化搜索的方式交了一下这个题目,需要注意的是:在初始化的时候应该初始化为-1,否则会出错,代码如下:
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std ;
const int maxn = 1005 ;
char numa[maxn] ;
char numb[maxn] ;
int num[maxn][maxn] ;
int lena ;
int lenb ;
int dp(int , int ) ;
int main()
{
//freopen("data.in" , "r" , stdin) ;
while(1)
{
cin.getline(numa , sizeof(numa)) ;
if(!cin)
break ;
cin.getline(numb , sizeof(numb)) ;
lena = strlen(numa ) ;
lenb = strlen(numb ) ;
memset(num , -1 , sizeof(num)) ;
dp(lena - 1 , lenb - 1) ;
printf("%d\n" , num[lena-1][lenb-1]) ;
}
return 0 ;
}
int dp(int n , int m)
{
int & ans = num[n][m] ;
if(n < 0 || m < 0)
return 0 ;
if(ans >= 0)
{
return ans ;
}
if(numa[n]==numb[m])
{
ans = dp(n - 1 , m - 1) + 1 ;
}
else if(dp(n-1 , m) >= dp(n , m - 1))
{
ans = dp(n-1 , m) ;
}
else ans = dp(n , m - 1) ;
return ans ;
}