UVA-1625-Color Length(DP LCS变形)
Color Length(UVA-1625)(DP LCS变形)
题目大意
输入两个长度分别为n,m(<5000)的颜色序列。要求按顺序合成同一个序列,即每次可以把一个序列开头的颜色放到新序列的尾部。
https://odzkskevi.qnssl.com/a68cbd3e27f46b4f02ea12b7b1a1abca
然后产生的新序列中,对于每一个颜色c,都有出现的位置,L(c)表示最小位置和最大位置之差,求L(c)总和最小的新序列。
分析
- LCS 是公共上升子序列,在动态转移的过程中,考虑第一个序列的 i ,和第二个序列的 j ,如果 i 和 j 相同,则
dp[i][j]=d[i-1][j-1]+1,若不相同,则dp[i][j]= max(dp[i-1][j],dp[i][j-1])。完成动态转移。 - 而这个题,是要让L(c)最小,在动态转移的过程中,我们要记录的值就是L(c)的和,同时还要考虑是不是有颜色开始或者结束。为了转移L(c)的和,我们还要用一个数组 C 来记录当前有多少颜色开始但尚未结束。(思路紫薯说的非常清楚)
dp[i][j] = min(dp[i-1][j]+c[i-1][j],dp[i][j-1]+c[i][j-1])i,j 表示前 i 个和前 j 个组成新串。- 做法就是先预处理两个串中每个字符的首次出现位置和末端出现位置。然后DP。DP状态转移思路其实不难想到,但是需要有些新的细节考虑。
- 总结一些细节
- 因为在两个串的合成过程中,可以有一个串一直未参与,而另一个串在一直合成。所以DP数组中下标0就是这个含义,但是如果字符串也从下标0开始,是不是有点麻烦了?所以第一个细节就是字符串从下标1开始。
- 可以先初始化 i = 0时候的情况,但是为了整体性,放在循环中处理会更好。(预处理的只能处理第一个为0,只取第二个串的情况,但是在DP过程中,每一层都要单独处理只取第一个串,第二个串为0,所以不如直接放在循环中进行考虑)
const int maxn = 5000+5;
const int INF = 1000000000;
char p[maxn],q[maxn];
int sp[26],sq[26],ep[26],eq[26];
int d[maxn],c[maxn];//其他人博客貌似都是两层,但其实一层就够了。
int main()
{
int T;cin>>T;
while(T--)
{
scanf("%s%s",p+1,q+1);
int n = strlen(p+1),m = strlen(q+1);
for(int i=1;i<=n;i++) p[i]-='A';
for(int j=1;j<=m;j++) q[j]-='A';
for(int i=0;i<26;i++)
{
sp[i] = sq[i] = INF;
ep[i] = eq[i] = 0;
}
//get到这个预处理,以前还没遇到过。
for(int i=1;i<=n;i++)
{
sp[p[i]] = min(sp[p[i]],i);
ep[p[i]] = i;
}
for(int i=1;i<=m;i++)
{
sq[q[i]] = min(sq[q[i]],i);
eq[q[i]] = i;
}
memset(c,0,sizeof c);memset(d,0,sizeof d);
for(int i=0;i<=n;i++)
{
for(int j = 0;j<=m;j++)
{
if(!j&&!i)continue;//两个都是0,就直接继续。
int v1=INF,v2 = INF;//对于这种特殊情况,只能先把两个值先寄存在v1,v2,并且赋值为INF。
if(i) v1=d[j]+c[j];
if(j) v2=d[j-1]+c[j-1];
d[j] = min(v1,v2);
if(i)
{
c[j] = c[j];
if(sp[p[i]]==i&&sq[p[i]]>j)c[j]++;//if中的条件,这里的细节也需要思考一下
if(ep[p[i]]==i&&eq[p[i]]<=j)c[j]--;
}
else if(j)
{
c[j] = c[j-1];
if(sq[q[j]] == j && sp[q[j]]>i)c[j]++;
if(eq[q[j]] == j && ep[q[j]]<=i)c[j]--;
}
}
}
printf("%d\n",d[m]);
}
return 0;
}
UVA-1625-Color Length(DP LCS变形)的更多相关文章
- UVa 1625 Color Length (DP)
题意:给定两个序列,让你组成一个新的序列,让两个相同字符的位置最大差之和最小.组成方式只能从一个序列前部拿出一个字符放到新序列中. 析:这个题状态表示和转移很容易想到,主要是在处理上面,dp[i][j ...
- UVA - 1625 Color Length[序列DP 代价计算技巧]
UVA - 1625 Color Length 白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束 和模拟赛那道环形DP很想,计算这 ...
- UVA - 1625 Color Length[序列DP 提前计算代价]
UVA - 1625 Color Length 白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束 和模拟赛那道环形DP很想,计算这 ...
- UVa 1625 - Color Length(线性DP + 滚动数组)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA 1625 Color Length 颜色的长度 (预处理+dp)
dp[i][j]表示前一个序列拿了i个颜色,后一个序列拿了j个颜色的最小花费. 转移的时候显然只能向dp[i+1][j],或dp[i][j+1]转移,每增加拿走一个颜色,之前已经出现但没结束的颜色个数 ...
- UVA 1625 "Color Length" (基础DP)
传送门 •参考资料 [1]:HopeForBetter •题意 •题解(by 紫书) •我的理解 用了一上午的时间,参考紫书+上述博文,终于解决了疑惑: 定义第一个颜色序列用串 s 表示,第二个用串 ...
- UVa 1625 Color Length
思路还算明白,不过要落实到代码上还真敲不出来. 题意: 有两个由大写字母组成的颜色序列,将它们合并成一个序列:每次可以把其中一个序列开头的颜色放到新序列的尾部. 对于每种颜色,其跨度定义为合并后的序列 ...
- uva 10453 dp/LCS变形
https://vjudge.net/problem/UVA-10453 给出一个字符串,问最少添加几个字符使其变为回文串,并输出任意一种答案.就是一个类似于LCS的题目,而且简化了一下,只会出现三种 ...
- poj1080--Human Gene Functions(dp:LCS变形)
Human Gene Functions Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17206 Accepted: ...
随机推荐
- 死磕了一题模拟 A掉的时候我是爽的
ZOJ 3490 没有题解. 一句话,要么贴代码,要么自己打. #include<cstdio> #include<iostream> #include<vector&g ...
- PTA 2-1 列出连通集【DFS+BFS基础】
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点. 输入格式: 输入第1 ...
- python 面向对象十三 枚举类
from enum import Enum Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', ...
- bzoj 1814: Ural 1519 Formula 1【插头dp】
设f[i][j][s]为轮廓线推到格子(i,j),状态为s的方案数 括号表示一段线的左端和右端,表示成左括号和右括号,状压的时候用1和2表示,0表示已经闭合 下面的蓝线是黄色格子的轮廓线,dp转移要把 ...
- 数位dp真·浅谈 By cellur925
预警:由于是从$Vergil$学长那里和$Mathison$大神那里学来的,所以清一色记忆化搜索!qwq 巨佬的数位dp讲解(未来的咕咕日报头条): https://www.luogu.org/blo ...
- 自己写的MD5加密原码
package com.wh.md5; import java.security.MessageDigest; import java.util.Arrays; /** * @author 王恒 * ...
- AJPFX总结方法的特点
它可以实现独立的功能; 必须定义在类里面; 它只有被调用才会执行; 它可以被重复使用; 方法结束后方法里的对象失去引用; 如何定义一个功能,并通过方法体现出来: ① 明确该功能运算后的结果.明确返 ...
- AJPFX关于Set接口学习笔记及总结
Set接口中的方法和Collection中方法一致的.Set接口取出方式只有一种,迭代器. |--HashSet:底层数据结构是哈希表,线程是不同步的.无序,高效: HashSet集合保证元素唯一性: ...
- poj1190 生日蛋糕
题意: 要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱.当i < M时,要求Ri > ...
- poj3436 Computer Factory
题意: 电脑公司生产电脑有N个机器,每个机器单位时间产量为Qi. 电脑由P个部件组成,每个机器工作时只能把有某些部件的半成品电脑(或什么都没有的空电脑)变成有另一些部件的半成品电脑或完整电脑(也可能移 ...