博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 10723 Cyborg Genes
阅读量:6547 次
发布时间:2019-06-24

本文共 2027 字,大约阅读时间需要 6 分钟。

UVA_10723

    首先这个题目肯定是按最长公共子序列的形式进行dp的,因为只有保证消去的一部分是最长公共子序列才能保证最后生成的序列最短。

    因此,在记录方案数的时候我们也按最长公共子序列的生成过程来记录即可,我们不妨用p[i][j]记录最长公共子序列的字符数,用f[i][j]表示到第一个字符串第i个位置、第二个字符串第j个位置时生成的序列最短的方案种数。

    当a[i]!=b[j]时,p[i][j]=max{p[i-1][j],p[i][j-1]},那么如果p[i][j]==p[i-1][j],f[i][j]+=f[i-1][j],如果p[i][j]==p[i][j-1],f[i][j]+=f[i][j-1]。用文字翻译过来就是说因为a[i]和b[j]是不同的,所以f[i][j]等于以a[i]结尾的最短的字符串的方案种数,加上以b[j]结尾的最短的字符串的方案种数。

    当a[i]==b[j]时,p[i][j]=p[i-1][j-1]+1,f[i][j]+=f[i-1][j-1]。试想,我们这样算会不会少算某些部分呢?因为毕竟也可以在a[i]和b[j]不配成一对的情况下生成最短的字符串呀。实际上,是可以证明f[i-1][j-1]包含了上述的情况的。譬如我们假设b[j]和a[i]前面的某个字符配成一对,同时生成了最短的字符串,那么这个字符串必然是以a[i]结尾的某个最短字符串,而以a[i]结尾的所有最短字符串的个数显然已经包含在f[i-1][j-1]之中了,因为f[i-1][j-1]本身就表示的是以a[i]为结尾的最短字符串的方案总数。

    实际上,这个类似证明求最长公共子序列时如果a[i]==b[j],那么取p[i][j]=p[i-1][j-1]+1一定是最优的。

#include
#include
#define MAXD 35 #define INF 1000000000 char a[MAXD], b[MAXD], p[MAXD][MAXD]; long long int f[MAXD][MAXD]; void solve() {
int i, j, k, lena, lenb, len; gets(a + 1); gets(b + 1); lena = strlen(a + 1); lenb = strlen(b + 1); memset(f, 0, sizeof(f)); for(i = 0; i <= lena; i ++) for(j = 0; j <= lenb; j ++) p[i][j] = INF; for(i = 0; i <= lenb; i ++) {
f[0][i] = 1; p[0][i] = 0; } for(i = 0; i <= lena; i ++) {
f[i][0] = 1; p[i][0] = 0; } for(i = 1; i <= lena; i ++) for(j = 1; j <= lenb; j ++) {
if(a[i] == b[j]) {
p[i][j] = p[i - 1][j - 1] + 1; f[i][j] += f[i - 1][j - 1]; } else {
p[i][j] = p[i - 1][j] > p[i][j - 1] ? p[i - 1][j] : p[i][j - 1]; if(p[i - 1][j] == p[i][j]) f[i][j] += f[i - 1][j]; if(p[i][j - 1] == p[i][j]) f[i][j] += f[i][j - 1]; } } printf("%d %lld\n", lena + lenb - p[lena][lenb], f[lena][lenb]); } int main() {
int t, tt; gets(b); sscanf(b, "%d", &t); for(tt = 0; tt < t; tt ++) {
printf("Case #%d: ", tt + 1); solve(); } return 0; }

转载地址:http://rirdo.baihongyu.com/

你可能感兴趣的文章
Lambda的前世今生
查看>>
黑马程序员-张老师基础加强3-内省
查看>>
TCP/IP模型简介和/etc/hosts文件说明
查看>>
UIButton常用属性
查看>>
主键自增归0
查看>>
杨辉三角
查看>>
mysql之 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11
查看>>
如何批量修改文件后缀的方法
查看>>
Effective STL 笔记
查看>>
[LeetCode] 1. Two Sum
查看>>
超时时间已到。在操作完成之前超时时间已过或服务器未响应。 (.Net SqlClient Data Provider)(转)...
查看>>
POJ2538 ZOJ1884 UVA10082 WERTYU【输入输出】
查看>>
HDU5620 KK's Steel(C++语言版)
查看>>
旋转卡壳
查看>>
2016/10/09
查看>>
自定义HorizontalScrollView的scrollBar
查看>>
c++学习笔记和思考
查看>>
27.Docker集群部署
查看>>
DNS保存
查看>>
IOS 多线程02-pthread 、 NSThread 、GCD 、NSOperationQueue、NSRunLoop
查看>>