zoukankan      html  css  js  c++  java
  • UVa 10723

    题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1664

    考察对于 (LCS) 的理解,最短字符串肯定是两串长度减去 (LCS) 的长度,而最短字符串的数量,也可以用类似 (LCS) 的方法求出

    (f[i][j]) 表示第一个字符串前 (i) 个字符和第二个字符串前 (j) 个字符所得到的 (LCS)(g[i][j]) 表示第一个字符串前 (i) 个字符和第二个字符串前 (j) 个字符所得到的最短字符串的数量,考虑当前 (LCS) 最后一个字符的位置

    如果 (s[i] == t[j]),说明 (i,j)(LCS) 的最后一个字符,(g[i][j] = g[i-1][j-1]),在上一个最短字符串后面添加一个字符,方案数不变

    如果 (s[i] != t[j]),考虑 (LCS) 是从哪里转移过来的
    如果 (f[i-1][j] > f[i][j-1]),则说明当前 (LCS) 最后一个字符之后只有一个不在 (LCS) 中的字符,因为字符间的相对位置不能改变,新添加的字符在最短字符串中必须在 (LCS) 最后一个字符之后,所以 (g[i][j] = g[i-1][j]),表示放置完 (LCS) 最后一个字符之后再添加新字符,反之亦然

    而如果 (f[i-1][j] = f[i][j-1]),则说明当前 (LCS) 最后一个字符之后有不止一个不在 (LCS) 中的字符,这些字符的顺序随意,所以 (g[i][j] = g[i-1][j] + g[i][j-1]),表示这些字符所放的顺序无所谓

    最后注意输入的字符串可能含有空格,所以要使用 (getline()) 函数读入

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 35;
    
    int T, n, m;
    int f[maxn][maxn], g[maxn][maxn];
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	scanf("%d", &T);
    	getchar();
    	int kase = 0;
    	while(T--){
    		string a, b;
    		getline(cin, a);
    		getline(cin, b);
    		n = a.length(), m = b.length();
    		a = " " + a;
    		b = " " + b;
    		
    		memset(f, 0, sizeof(f));
    		memset(g, 0, sizeof(g));
    		g[0][0] = 1;
    		for(int i = 1 ; i <= max(n, m) ; ++i) g[i][0] = g[0][i] = 1; 
    		for(int i = 1 ; i <= n ; ++i){
    			for(int j = 1 ; j <= m ; ++j){
    				if(a[i] == b[j]){
    					f[i][j] = max(f[i][j], f[i-1][j-1] + 1);
    					g[i][j] = g[i-1][j-1];
    				} else{
    					if(f[i-1][j] > f[i][j-1]){
    						f[i][j] = max(f[i-1][j], f[i][j-1]);
    						g[i][j] = g[i-1][j];
    					} else if(f[i-1][j] < f[i][j-1]){
    						f[i][j] = max(f[i-1][j], f[i][j-1]);
    						g[i][j] = g[i][j-1];
    					} else{
    						f[i][j] = max(f[i-1][j], f[i][j-1]);
    						g[i][j] = g[i-1][j] + g[i][j-1];
    					}
    				}
    			}
    		}
    		
    		printf("Case #%d: %d %d
    ", ++kase, n + m - f[n][m], g[n][m]);
    	} 
    	return 0;
    }
    
  • 相关阅读:
    将Python的Django框架与认证系统整合的方法
    将Python的Django框架与认证系统整合的方法
    Python的Asyncore异步Socket模块及实现端口转发的例子
    每天一个linux命令(3):du命令
    每天一个linux命令(2):file 命令
    Ubantu 使用extundelete恢复数据
    ubantu 单用户模式进入系统
    GDB 调试解析
    服务器搭建5 Samba实现文件共享
    服务器搭建4 安装其它库
  • 原文地址:https://www.cnblogs.com/tuchen/p/15080222.html
Copyright © 2011-2022 走看看