ZOJ-2366 Weird Dissimilarity 动态规划+贪心
题意:现给定一个字符集中一共Z个元素的环境,给出一个Z*Z的数组,表示从i到j之间的距离。给定两组字符串,分别问包含着两个字符串(给定的字符串为所求字符串的子序列不是子串)对应位的距离和值最小为多少?输出这两个字符串。
分析:该题的状态还是比较好开设的,设dp[i][j]表示a串的前i个字符和b串的前j个字符被包含后的最小开销,于是动态转移方程:
dp[i][j] = min(dp[i][j], dp[i-1][j] + wa[sa[i]]); 其中wa数组表示某个字符与另外一个最小花费的字符匹配,sa[i]表示a串的第i个字符
dp[i][j] = min(dp[i][j], dp[i][j-1] + wb[sb[j]]); 意义同上一个转移类似,均表示一个字符与一个最便宜的字符匹配
dp[i][j] = min(dp[i][j], dp[i-1][j-1] + dist[sa[i]][sb[j]]); 该方程的意义为两个串均拿出一个字符来匹配
这里需要说明的是补全两个串的最长长度最多为两个串长度之和,由上面的转移可以知道,每个位至少会有一个字符是属于串a或者是串b。
还有一个地方要特别注意的是,给定字符集可能会有超过127的ascii码,并且编号之后可能有编号大于127,因此前面自己写的sa[i] = mp[sa[i]]一直RE就是出现了负数,改成了unsigned char了。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std; const int Z = ;
const int N = ;
int d[Z][Z];
map<char, int>mp;
unsigned char str[Z], sa[N], sb[N];
int na[N], nb[N];
int la, lb, wa[Z], wb[Z], ca[Z], cb[Z];
int idxa, idxb, dp[N][N], path[N][N];
char qa[N<<], qb[N<<];
// wa、wb数组分别用来说明sa串中的某字符的最佳匹配和sb串中某字符的最佳匹配
// ca、cb数组记录在wa、wb数组取得最优解的情况下所对应的字符 void dfs(int i, int j) {
if (!i && !j) return;
if (i > && j > && dp[i][j] == dp[i-][j-] + d[sa[i]][sb[j]]) {
qa[idxa++] = str[sa[i]];
qb[idxb++] = str[sb[j]];
dfs(i-, j-);
} else if (i > && dp[i][j] == dp[i-][j] + wa[sa[i]]){
qa[idxa++] = str[sa[i]];
qb[idxb++] = str[ca[sa[i]]];
dfs(i-, j);
} else {
qa[idxa++] = str[cb[sb[j]]];
qb[idxb++] = str[sb[j]];
dfs(i, j-);
}
} void gao() {
// 最坏情况需要构造出长度为la+lb长度的串
memset(dp, 0x3f, sizeof (dp));
dp[][] = ;
for (int i = ; i <= la; ++i) {
for (int j = ; j <= lb; ++j) {
if (i > ) {
dp[i][j] = min(dp[i][j], dp[i-][j] + wa[sa[i]]);
}
if (j > ) {
dp[i][j] = min(dp[i][j], dp[i][j-] + wb[sb[j]]);
}
if (i > && j > ) {
dp[i][j] = min(dp[i][j], dp[i-][j-] + d[sa[i]][sb[j]]);
}
}
}
printf("%d\n", dp[la][lb]);
idxa = idxb = ;
dfs(la, lb);
for (int i = idxa-; i >= ; --i) {
putchar(qa[i]);
}
puts("");
for (int i = idxb-; i >= ; --i) {
putchar(qb[i]);
}
puts("");
} int main() {
int T;
scanf("%d%", &T);
while (T--) {
mp.clear();
memset(wa, 0x3f, sizeof (wa));
memset(wb, 0x3f, sizeof (wb));
scanf("%s", str+);
int len = strlen((char*)(str+));
for (int i = ; i <= len; ++i) {
mp[str[i]] = i;
}
scanf("%s %s", sa+, sb+);
la = strlen((char *)(sa+)), lb = strlen((char *)(sb+));
for (int i = ; i <= la; ++i) {
sa[i] = mp[sa[i]];
}
for (int i = ; i <= lb; ++i) {
sb[i] = mp[sb[i]];
}
for (int i = ; i <= len; ++i) {
for (int j = ; j <= len; ++j) {
scanf("%d", &d[i][j]);
if (wa[i] > d[i][j]) {
wa[i] = d[i][j], ca[i] = j;
}
if (wb[j] > d[i][j]) {
wb[j] = d[i][j], cb[j] = i;
}
}
}
gao();
}
return ;
}
ZOJ-2366 Weird Dissimilarity 动态规划+贪心的更多相关文章
- hdu 1257 最少拦截系统(动态规划 / 贪心)
最少拦截系统 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- 洛谷P1095守望者的逃离题解-伪动态规划/贪心
链接 题目描述 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很 ...
- 二叉树遍历问题、时间空间复杂度、淘汰策略算法、lru数据结构、动态规划贪心算法
二叉树的前序遍历.中序遍历.后序遍历 前序遍历 遍历顺序规则为[根左右] ABCDEFGHK 中序遍历 遍历顺序规则为[左根右] BDCAEHGKF 后序遍历 遍历顺序规则为[左右根] DCBHKGF ...
- ZOJ 3699 Dakar Rally(贪心)
这是一道贪心题,他的贪心思想很容易想明白,我们保证油箱里的油始终是最便宜的我们最后的花费就能是最少的.实现方法就是:比如现在在i点,我们看邮箱满载能最远到达哪里,不妨设最远到达j,(j >= i ...
- ZOJ 2002 Copying Books 二分 贪心
传送门:Zoj2002 题目大意:从左到右把一排数字k分,得到最小化最大份,如果有多组解,左边的尽量小. 思路:贪心+二分(参考青蛙过河). 方向:从右向左. 注意:有可能最小化时不够k分.如 ...
- CF1088F Ehab and a weird weight formula 贪心 倍增
CF1088F Ehab and a weird weight formula 题意 给定一棵树,点有点权,其中这棵树满足除了权值最小的点外,每个点至少有一个点权小于它的相邻点. 要求你重新构建这棵树 ...
- [ZOJ 3662] Math Magic (动态规划+状态压缩)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3662 之前写过这道题,结果被康神吐槽说代码写的挫. 的确,那时候 ...
- ZOJ 3941 Kpop Music Party 贪心
题目链接: http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3941 题解: 先吧所给的区间合并,得到若干个独立的区间. 然后从左 ...
- ZOJ 3607 Lazier Salesgirl(贪心)
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3607 题意:一个卖面包的小姑娘,给第i个来买面包的人的价格是pi, ...
随机推荐
- Class.forName("ClassName")与ClassName.class的区别
引发问题的来源:最近在看比较深入的JVM相关的书,不得不感慨,JVM确实是比较深奥,很多地方难以理解不说,在网上还找不到什么资料,发现一个左思右想都想不明白的问题上网来搜索,结果基本上都是从书上cop ...
- WinCE Show App Icon
找个图片,例如背景透明的jpg或png,上http://www.pic2icon.com/smartphone_wince_icon_generator.php这个网站转换下. 在项目属性中,设为图标 ...
- .Net额外小工具
http://blog.csdn.net/zhumi/article/details/49076 用于编写单元测试的 NUnit用于创建代码文档资料的 NDoc用于生成解决方案的 NAnt用于生成代码 ...
- linux ar命令
当我们的程序中有经常使用的模块,而且这种模块在其他程序中也会用到,这时按照软件重用的思想,我们应该将它们生成库,使得以后编程可以减少开发代码量.这里介绍命令ar,用来对库操作. 1.ar基本用法 ar ...
- hdwiki 学习笔记 01
一.href =“”里的参数写法 <!--{if $hotname[url]}-->{$hotname[url]} <!--{else}-->index.php?doc-inn ...
- 【20160924】GOCVHelper 图像增强部分(4)
//使得rect区域半透明 Mat translucence(Mat src,Rect rect,int idepth){ Mat dst = src.clone(); ...
- Entity Framework 第五篇 状态跟踪
本人建议尽量使用EntityState来表名Entry的状态,而不要使用Configuration.AutoDetectChangesEnabled自动状态跟踪,为什么我这么建议呢?他们到底有什么异同 ...
- 内存恶鬼drawRect
标题有点吓人,但是对于drawRect的评价倒是一点都不过分.在平日的开发中,随意覆盖drawRect方法,稍有不慎就会让你的程序内存暴增.下面我们来看一个例子. 去年的某天午后,北京的雾霾依旧像现在 ...
- reactjs源码
'use strict'; var EventConstants = _dereq_(15);var EventPropagators = _dereq_(19);var ExecutionEnvir ...
- Android SDK版本和ADT版本
Android SDK版本和ADT版本 Android早期的版本号有点“混乱”,比如Android 2.2对应的ADT版本为ADT-0.9.9而Android 2.3对应的的ADT版本则突然“跃迁 ...