UVA 531 - Compromise
题意:给你俩段文章,求其中单词的最长子序列
思路:最长公共子序列 回溯
ps:用string容器储存每一个单词,便于比较;其次注意初始化;回溯用栈挺方便的
最长公共子序列dp方程:
if(a[i]==b[j])
table[i][j]=table[i-1][j-1]+1;
else table[i][j]=max(table[i][j-1],table[i-1][j]);
参考代码:Click_here
代码如下:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <stack> 5 6 using namespace std; 7 #define M 1001 8 9 string str1[M],str2[M]; 10 int table[M][M]; 11 12 int dpstr1[M][M],dpstr2[M][M]; 13 stack<string> s; 14 15 int p,q; 16 int size1,size2; 17 18 void dateclear()//初始化 19 { 20 memset(table,0,sizeof(table)); 21 memset(dpstr1,0,sizeof(dpstr1)); 22 memset(dpstr2,0,sizeof(dpstr2)); 23 } 24 25 void datecin()//数据输入 26 { 27 dateclear(); 28 int i; 29 for(i=2;;i++) 30 { 31 cin>>str1[i]; 32 if(str1[i]=="#") 33 break; 34 } 35 size1=i-1; 36 for(i=1;;i++) 37 { 38 cin>>str2[i]; 39 if(str2[i]=="#") 40 break; 41 } 42 size2=i-1; 43 } 44 45 void datecal()//计算最大子序 46 { 47 int i,j; 48 //cout<<size1<<':'<<size2<<endl; 49 for(i=1;i<=size1;i++) 50 { 51 for(j=1;j<=size2;j++) 52 { 53 if(str1[i]==str2[j]) 54 { 55 // cout<<table[i][j]; 56 table[i][j]=table[i-1][j-1]+1; 57 dpstr1[i][j]=i-1; 58 dpstr2[i][j]=j-1; 59 } 60 else 61 { 62 if(table[i][j-1]>table[i-1][j]) 63 { 64 table[i][j]=table[i][j-1]; 65 dpstr1[i][j]=i; 66 dpstr2[i][j]=j-1; 67 } 68 else 69 { 70 table[i][j]=table[i-1][j]; 71 dpstr1[i][j]=i-1; 72 dpstr2[i][j]=j; 73 } 74 } 75 } 76 } 77 } 78 79 void showres() 80 { 81 p=size1,q=size2; 82 while(p>=1&&q>=1) 83 { 84 85 if(str1[p]==str2[q]) 86 { 87 s.push(str1[p]); 88 } 89 int t=p; 90 p=dpstr1[p][q]; 91 q=dpstr2[t][q]; 92 } 93 while(s.size()>1) 94 { 95 cout<<s.top()<<' '; 96 s.pop(); 97 } 98 cout << s.top()<<endl; 99 s.pop(); 100 } 101 102 void showtab() 103 { 104 for(int j=0;j<=size2;j++) 105 { 106 for(int i=0;i<=size1;i++) 107 cout<<table[i][j]<<' '; 108 cout<<endl; 109 } 110 cout<<endl; 111 } 112 113 int main() 114 { 115 while(cin>>str1[1]) 116 { 117 datecin(); 118 datecal(); 119 showres(); 120 } 121 return 0; 122 }