uva 531·Compromise(LCS---路径打印)

题目:

In a few months the European Currency Union will become a reality. However, to join the club, the Maastricht criteria must be fulfilled, and this is not a trivial task for the countries (maybe except for Luxembourg). To enforce that Germany will fulfill the criteria, our government has so many wonderful options (raise taxes, sell stocks, revalue the gold reserves,...) that it is really hard to choose what to do。

Therefore the German government requires a program for the following task:

Two politicians each enter their proposal of what to do. The computer then outputs the longest common subsequence of words that occurs in both proposals. As you can see, this is a totally fair compromise (after all, a common sequence of words is something what both people have in mind).

Your country needs this program, so your job is to write it for us.

Input Specification

The input file will contain several test cases.

Each test case consists of two texts. Each text is given as a sequence of lower-case words, separated by whitespace, but with no punctuation. Words will be less than 30 characters long. Both texts will contain less than 100 words and will be terminated by a line containing a single ‘#‘.

Input is terminated by end of file.

Output Specification

For each test case, print the longest common subsequence of words occuring in the two texts. If there is more than one such sequence, any one is acceptable. Separate the words by one blank. After the last word, output a newline character.

Sample Input

die einkommen der landwirte
sind fuer die abgeordneten ein buch mit sieben siegeln
um dem abzuhelfen
muessen dringend alle subventionsgesetze verbessert werden
#
die steuern auf vermoegen und einkommen
sollten nach meinung der abgeordneten
nachdruecklich erhoben werden
dazu muessen die kontrollbefugnisse der finanzbehoerden
dringend verbessert werden
#

Sample Output

die einkommen der abgeordneten muessen dringend verbessert werden解析:简单的LCS不过加了路径的打印,和01背包的路径打印有所不同     这道题的输入方法值得学习,输入一大串字符串直到出现字符“#”,为止。     可以用一个二维数组,先输入第一个单词,判断首字母是不是“#”。

 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=110;
 4 char str1[maxn][32],str2[maxn][32];
 5 int dp[maxn][maxn],path[maxn][maxn],flag;
 6 void print(int x,int y)
 7 {
 8     if(!x||!y)
 9         return;
10     if(path[x][y]==1)
11     {
12         print(x-1,y-1);
13         if(flag)
14             printf(" ");
15         else
16             flag=1;
17         printf("%s",str1[x]);
18     }
19     else if(path[x][y]==0)
20         print(x-1,y);
21     else
22         print(x,y-1);
23 }
24 int main()
25 {
26     int num1,num2;
27     while(scanf("%s",str1[1])==1)
28     {
29         num1=1;
30         num2=0;
31         if(str1[1][0]!=‘#‘)
32         {
33             for(int i=2;;i++)
34             {
35                 scanf("%s",str1[i]);
36                 if(str1[i][0]==‘#‘) break;
37                 num1++;
38             }
39         }
40         for(int i=1;;i++)
41         {
42             scanf("%s",str2[i]);
43             if(str2[i][0]==‘#‘) break;
44             num2++;
45         }
46         memset(dp,0,sizeof(dp));
47         for(int i=1;i<=num1;i++)
48         {
49             for(int j=1;j<=num2;j++)
50             {
51                 if(!strcmp(str1[i],str2[j]))
52                 {
53                     dp[i][j]=dp[i-1][j-1]+1;
54                     path[i][j]=1;
55                 }
56                 else if(dp[i-1][j]>dp[i][j-1])
57                 {
58                     dp[i][j]=dp[i-1][j];
59                     path[i][j]=0;
60                 }
61                 else
62                 {
63                     dp[i][j]=dp[i][j-1];
64                     path[i][j]=-1;
65                 }
66             }
67         }
68         flag=0;
69         print(num1,num2);
70         printf("\n");
71     }
72     return 0;
73 }

时间: 2024-11-15 12:34:54

uva 531·Compromise(LCS---路径打印)的相关文章

UVa 531 - Compromise

题目:给你两个文章,求里面最多的按顺序出现的单词. 分析:dp,LCS(最大公共子序列).直接求最大公共子序列,每个单词当做一个元素即可: 注意记录路径:如果匹配成功记录前驱,否则取前面取得的最大值的前驱(这里合成一个数字): 设状态f(i,j)为串S[0..i-1]与串T[0..j-1]的最大公共子序列. 有状态转移方程: f(i,j)= f(i-1,j-1)                                  {S[i-1]与T[j-1]相同} f(i,j)= max(f(i-

POJ 2250 &amp; UVA 531 Compromise(字符串、 最长公共子序列)

Compromise 题目: 题目大意: 这里有两篇短文,每篇短文有若干个单词,求这两篇短文中的最长公共子序列,并将其输出来! 没篇短文输入 为 "#" 时,结束该篇短文的输入. 这道题是多组测试数据,如果只写一组,那么就会 WA,我因为这就被 WA 了一次! 最长公共子序列的解法,就不多说了,基本上所有的算法书上都有介绍讲解. 这道题,题意和解法我认为都不是难点,我个人认为难点是在最长公共子序列的保存记录上. 对于最长公共子序列的记录保存上,我用了 C++ 的 STL 中的strin

POJ 2250 Compromise (UVA 531)

LCS问题,基础DP. 让我很忧伤的WA了很多次.只是一个LCS问题,需要记录一下路径. 自己的想办法记录path出错,最后只好用标记. 没有什么优化,二维数组,递归打印,cin.eof() 来识别 end of file 标识. 至于单词用map 映射的.其实也用不着,直接二维string或者 二维char 然后strcmp 也行. Special Judge 交 UVA 531 奇怪的PE了... 然后改成 flag 标记 输出 空格.终于都AC了. #include<cstdio> #i

UVA - 624CD(递推+ 路径打印)

题目: UVA - 624CD(递推+ 路径打印) 题目大意:给出一组数据,给定一个N,问这些数据能否拼凑出不大于N的最接近N的数据,可以的话输出最接近N的数据,并且打印出最长路径(要求要找输入的顺序). 解题思路:dp[j]:代表凑出J这个数值最多需要几个数.d[j] = Max (d[j - v[i]] + 1. 打印路径,如果取得是最小值,那么顺着dp标记的值的减小就可以找到路径,但是取的是最大值,这样它的下一个并不能直接靠dp数组的值来判断,而是要判断到最后是否最终的值等于0.用回溯.

poj 2250 Compromise dp lcs 路径输出

点击打开链接题目链接 Compromise Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6520   Accepted: 2922   Special Judge Description In a few months the European Currency Union will become a reality. However, to join the club, the Maastricht criteria

The Pilots Brothers&#39; refrigerator-DFS路径打印

I - The Pilots Brothers' refrigerator Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description The game "The Pilots Brothers: following the stripy elephant" has a quest where a player needs to op

UVa 10192 - Vacation ( LCS 最长公共子串)

链接:UVa 10192 题意:给定两个字符串,求最长公共子串的长度 思路:这个事最长公共子串的直接应用 #include<stdio.h> #include<string.h> int max(int a,int b) { return a>b?a:b; } int main() { char s[105],t[105]; int i,j,k=0,m,n,dp[105][105]; while(gets(s)!=NULL){ if(strcmp(s,"#"

UVA 624 CD 记录路径DP

开一个数组p 若dp[i-1][j]<dp[i-1][j-a[i]]+a[i]时就记录下p[j]=a[i];表示此时放进一个轨道 递归输出p #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #in

DAG镶嵌模型+原始路径打印

DP矩形镶嵌,打印路径与最长公共子序列相似. 1 #include<stdio.h> 2 #include<string.h> 3 #define doumax(a,b) (a>b?a:b) 4 const int maxn=100; 5 int mat[maxn][maxn],dp[maxn],n; 6 struct node{ 7 int a; 8 int b; 9 void dousort(void) 10 { 11 if(a<b){ 12 int temp=a;