hdu 1159
题意:求两个串的最长公共子序列
#include
#include
#include
#define size 1000
using namespace std;
char str1[size],str2[size];
int dp[size][size];
int main()
{
int len1,len2;
while(scanf("%s",str1)!=EOF)
{
getchar();
scanf("%s",str2);
len1=strlen(str1);
len2=strlen(str2);
memset(dp,0,sizeof(dp));
for(int i=1;i<=len1;i++)
{
for(int j=1;j<=len2;j++)
{
if(str1[i-1]==str2[j-1] )
{
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[len1][len2]);
}
return 0;
}
hdu 1080
题意:两个字符串,每个字符串中都可以插入'-',保证最后两串的长度相等,之后让两串对齐,两串相同位置的字母组成的字符匹配有一个值,问这些值的和最大是多少
#include
#include
#include
#define INF 0x3fffffff
using namespace std;
int tmp[5][5]=
{
{5,-1,-2,-1,-3},
{-1,5,-3,-2,-4},
{-2,-3,5,-2,-2},
{-1,-2,-2,5,-1},
{-3,-4,-2,-1,0}
};
int tt(char c)
{
if(c=='A') return 0;
else if(c=='C') return 1;
else if(c=='G') return 2;
else return 3;
}
int dp[110][110];
int main()
{
int len1,len2;
char str[110];
int a[110],b[110];
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %s",&len1,str);
int i,j;
for(i=0;i
题意:
给你两个单词,然后你要把两个单词拼接成一个新单词,使得新单词的子序列中包含两个单词,并且要使这个新单词最短
基本思路:
求最长公共子序列,令这个序列只输出一次就可以使新单词最短
记录路径:
增加二维数组road记录状态转移路径
road[i][j] = 0 表示road[i][j]由road[i-1][j-1]转移过来,即a[i-1]与b[j-1]属于最长公共子序列中的元素,扫描路径时将hash[i-1]赋值为j-1表示a串的i-1匹配b串的j-1【其中hash初始时全为-1】
road[i][j] = 1 表示road[i][j]由road[i-1][j]转移过来
road[i][j] = 2 表示road[i][j]由road[i][j-1]转移过来
输出答案:
先设置start变量【表示b串的当前位置】,扫描a串
①当对于a[i]有hash[i]==-1,说明a[i]不是最长公共子序列中的元素,直接输出并且continue;
②否则b串输出从start到hash[i]的值,因为a[i]跟b[hash[i]]匹配嘛,所以输出b[hash[i]]就不用输出a[i]勒,然后start变为hash[i] + 1;
#include
#include
#include
using namespace std;
int main()
{
char str1[110],str2[110];
int hash[110];
int dp[110][110];
int roat[110][110];
int len1,len2;
int i,j;
while(scanf("%s %s",str1,str2)!=EOF)
{
memset(dp,0,sizeof(dp));
memset(hash,-1,sizeof(hash));
memset(roat,-1,sizeof(roat));
len1=strlen(str1);
len2=strlen(str2);
for(i=1;i<=len1;i++)
{
for(j=1;j<=len2;j++)
{
if(str1[i-1]==str2[j-1])
{
dp[i][j]=dp[i-1][j-1]+1;
roat[i][j]=0; //cout<<"**********"<