poj1080

来源:互联网 发布:linux vi 全部删除 编辑:程序博客网 时间:2024/06/09 21:30

题目有难度,有点类似于lcs的分析,题目大意为:每个case给定两个字符串,要求在两个串中插入必要的‘-‘使得两串匹配按照题目所给定value值最大。理解题意时要注意如下:

1)只能在原串中插入字符’-‘,使得两串的长度相等,但原串本身字符的顺序不能改变,这是该题的关键点

2)可以在任意位置插入任意数量的’-‘,只要不违反条件1)

理解了上述两点后,接着就要确定dp及状态方程了。分析如下:

我们令dp[i][j]表示第一个串中前i个字符,第二个串中前j个字符,所组成的两个字符串的最大value。则第二个字符串中最末尾的字符next[j]可以与第一个字符串中的字符first[k]匹配(1<=k<=i ),同时可以匹配符号‘-’,而匹配符号可以分为多种情况,符号‘-’的位置不同,则表达式就不同,但均可以归为一种情况即:dp[i][j-1]+value[1][next[j]-'A']。

那么动态转移方程就出来了:dp[i][j]=max{dp[k-1][j-1]+value[first[k]-'A'][next[j]-'A']+value[1][first[index]-'A']}

详细见代码: 204K+32MS

#include <stdio.h>#include <stdlib.h>#define Max 110#define Maxx(a,b) (a)>(b)?(a):(b)char first[Max]; // 第一个串char next[Max]; // 第二个串char help[Max]; // 辅助数组int dp[Max][Max]; int value[20][20]; //记录题意valueint Case;int len1,len2; // 串长1和2int main(){int i,j,k,index; //初始化题意valuevalue[0][0]=5,value[0][1]=-3,value[0][2]=-1,value[0][6]=-2,value[0][19]=-1;value[2][0]=-1,value[2][1]=-4,value[2][2]=5,value[2][6]=-3,value[2][19]=-2;value[6][0]=-2,value[6][1]=-2,value[6][2]=-3,value[6][6]=5,value[6][19]=-2;value[19][0]=-1,value[19][1]=-1,value[19][2]=-2,value[19][6]=-2,value[19][19]=5;value[1][0]=-3,value[1][2]=-4,value[1][6]=-2,value[1][19]=-1;scanf("%d",&Case);while(Case--){scanf("%d",&len1);getchar();scanf("%s",help); //转化为第一个串,以1开头for(i=1;i<=len1;i++)first[i]=help[i-1];scanf("%d",&len2);getchar();scanf("%s",help);for(i=1;i<=len2;i++) // 同理next[i]=help[i-1];dp[0][0]=0; //初始化两个长度均为0的串匹配最大value为0//初始化第二个串长度为0,第一个串长度为i(1<=i<=len1)匹配的最大长度即为第一个串中的每个字符与符号’-‘匹配for(i=1;i<=len1;i++){                           dp[i][0]=0; for(j=1;j<=i;j++)dp[i][0]+=value[1][first[j]-'A'];}//同理,初始化第一个串长度为0for(i=1;i<=len2;i++){dp[0][i]=0;for(j=1;j<=i;j++)dp[0][i]+=value[1][next[j]-'A'];}for(i=1;i<=len1;i++) //求解dp,注意顺序必须为这样,才能利用已知dp求解未知dpfor(j=1;j<=len2;j++){                                     //两种特殊情况,特殊处理,分别为末尾匹配和与’-‘匹配dp[i][j]=dp[i-1][j-1]+value[first[i]-'A'][next[j]-'A']; dp[i][j]=Maxx(dp[i][j],dp[i][j-1]+value[1][next[j]-'A']);for(k=1;k<i;k++){ // 一般情况,当1<=k<i时int temp=dp[k-1][j-1]+value[first[k]-'A'][next[j]-'A'];for(index=k+1;index<=i;index++)temp+=value[1][first[index]-'A'];dp[i][j]=Maxx(dp[i][j],temp);}}printf("%d\n",dp[len1][len2]); //输出最大value}return 0;}


 


 

0 0