UVA 1625 "Color Length" (基础DP)
•参考资料
[1]:HopeForBetter
•题意
•题解(by 紫书)
•我的理解
用了一上午的时间,参考紫书+上述博文,终于解决了疑惑;
定义第一个颜色序列用串 s 表示,第二个用串 t 表示,下标均从 1 开始;
定义dp(i,j)表示串 s 的前 i 个字符与串 t 的前 j 个字符合并的最小值;
' ? ' 是加什么呢?
分析一下,当前的新序列包含哪些类型的字符:
1)当前新序列包含字符 ch 的开始和结束;
2)当前新序列只包含字符 ch 的开始,而不包含其结束;
3)当前新序列不包含字符 ch;
就情况①,将 si 插入到尾部后,你会发现,这个新插入的元素只会影响 1) 类型字符,怎么影响呢?
当前字符 si 的插入会使得 1) 类型的字符首尾距离增加 1;
那么,情况①中的 ' ? ' 指的就是 s 串的前 i-1 个字符与 t 串中的前 j 个字符的 1) 类型的字符个数;
情况②同理;
那么,如何求解 "s 串的前 i-1 个字符与 t 串中的前 j 个字符的 1) 类型的字符个数" 呢?
定义 w(i,j) 表示串 s 的前 i 个字符与串 t 的前 j 个字符包含的 1) 类型的字符总个数;
struct Data
{
int fir,las;
Data(int fir=INF,int las=):fir(fir),las(las){}
};
int w[maxn][maxn]; void Preset()
{
/**
a[i].fir:字符 'A'+i 在串s中第一次出现的位置
a[i].las:字符 'A'+i 在串s中最后一次出现的位置
b[i].fir:字符 'A'+i 在串t中第一次出现的位置
b[i].las:字符 'A'+i 在串t中最后一次出现的位置
*/
Data a[],b[];
for(int i=;i <= n;++i)
{
Data &tmp=a[s[i]-'A'];
tmp.fir=min(tmp.fir,i);
tmp.las=i;
}
for(int i=;i <= m;++i)
{
Data &tmp=b[t[i]-'A'];
tmp.fir=min(tmp.fir,i);
tmp.las=i;
}
w[][]=;
for(int i=;i <= n;++i)
{
for(int j=;j <= m;++j)
{
if(i)
{
w[i][j]=w[i-][j];
int k=s[i]-'A';
if(a[k].fir == i && b[k].fir > j)///判断si是否为首次出现的
w[i][j]++;
if(a[k].las == i && b[k].las <= j)///判断si是否为结尾字符
w[i][j]--;
}
if(j)
{
w[i][j]=w[i][j-];
int k=t[j]-'A';
if(b[k].fir == j && a[k].fir > i)///判断tj是否为首次出现的
w[i][j]++;
if(b[k].las == j && a[k].las <= i)///判断tj是否为结尾字符
w[i][j]--;
}
}
}
}求解w(i,j)
求解完 w(i,j) 后,状态转移方程也就完成了:
•Code
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define INFll 0x3f3f3f3f3f3f3f3f
#define ll long long
const int maxn=5e3+; int n,m;
char s[maxn];
char t[maxn];
struct Data
{
int fir,las;
Data(int fir=INF,int las=):fir(fir),las(las){}
};
int w[maxn][maxn];
ll dp[maxn][maxn]; void Preset()
{
/**
a[i].fir:字符 'A'+i 在串s中第一次出现的位置
a[i].las:字符 'A'+i 在串s中最后一次出现的位置
b[i].fir:字符 'A'+i 在串t中第一次出现的位置
b[i].las:字符 'A'+i 在串t中最后一次出现的位置
*/
Data a[],b[];
for(int i=;i <= n;++i)
{
Data &tmp=a[s[i]-'A'];
tmp.fir=min(tmp.fir,i);
tmp.las=i;
}
for(int i=;i <= m;++i)
{
Data &tmp=b[t[i]-'A'];
tmp.fir=min(tmp.fir,i);
tmp.las=i;
}
w[][]=;
for(int i=;i <= n;++i)
{
for(int j=;j <= m;++j)
{
if(i)
{
w[i][j]=w[i-][j];
int k=s[i]-'A';
if(a[k].fir == i && b[k].fir > j)///判断si是否为首次出现的
w[i][j]++;
if(a[k].las == i && b[k].las <= j)///判断si是否为结尾字符
w[i][j]--;
}
if(j)
{
w[i][j]=w[i][j-];
int k=t[j]-'A';
if(b[k].fir == j && a[k].fir > i)///判断tj是否为首次出现的
w[i][j]++;
if(b[k].las == j && a[k].las <= i)///判断tj是否为结尾字符
w[i][j]--;
}
}
}
}
ll Solve()
{
Preset();
dp[][]=;
for(int i=;i <= n;++i)
{
for(int j=;j <= m;++j)
{
if(!(i+j))
continue;
dp[i][j]=INFll; if(i)
dp[i][j]=min(dp[i][j],dp[i-][j]+w[i-][j]);
if(j)
dp[i][j]=min(dp[i][j],dp[i][j-]+w[i][j-]);
}
}
return dp[n][m];
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
scanf("%s%s",s+,t+);
n=strlen(s+);
m=strlen(t+); printf("%lld\n",Solve());
}
return ;
}
UVA 1625 "Color Length" (基础DP)的更多相关文章
- 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 ...
- UVA 1625 Color Length 颜色的长度 (预处理+dp)
dp[i][j]表示前一个序列拿了i个颜色,后一个序列拿了j个颜色的最小花费. 转移的时候显然只能向dp[i+1][j],或dp[i][j+1]转移,每增加拿走一个颜色,之前已经出现但没结束的颜色个数 ...
- UVa 1625 Color Length
思路还算明白,不过要落实到代码上还真敲不出来. 题意: 有两个由大写字母组成的颜色序列,将它们合并成一个序列:每次可以把其中一个序列开头的颜色放到新序列的尾部. 对于每种颜色,其跨度定义为合并后的序列 ...
- 动态规划(模型转换):uvaoj 1625 Color Length
[PDF Link]题目点这里 这道题一眼就是动态规划,然而貌似并不好做. 如果不转换模型,状态是难以处理的. 巧妙地转化:不直接求一种字母头尾距离,而是拆开放到状态中. #include <i ...
- UVA 12405 Scarecrow (基础DP)
题意: 给出一个1*N的矩阵(就是一行的格子),其中部分格子可以有草,部分无草,现在要求放置一些稻草人在某些格子上,每个稻草人可以覆盖3个连续格子,为使得有草的格子都能被覆盖,问最少放置几个稻草人. ...
- UVA 10037 Bridge (基础DP)
题意: 过河模型:有n个人要渡河,每个人渡河所耗时可能不同,只有1只船且只能2人/船,船速取决于速度慢的人.问最少耗时多少才能都渡完河? 思路: n<2的情况比较简单. 考虑n>2的情况, ...
随机推荐
- 【心有猛虎】react-lesson
这个项目标识:构建一套适合 React.ES6 开发的脚手架 项目地址为:https://github.com/ZengTianShengZ/react-lesson 运行的是第一课,基本上可以当作是 ...
- 【POJ 3261】Milk Patterns
[链接]h在这里写链接 [题意] 给你一个长度为n的序列. 问你能不能在其中找到一个最长的子串. 这个子串至少出现了k次. [题解] 长度越长,就越不可能出现k次 后缀数组+二分. N最大为2 ...
- FJWC2018
晚上水到8:40,感觉药丸. 把电脑带回寝室,大半夜敲键盘…… bzoj5254红绿灯 泰迪每天都要通过一条路从家到学校,这条路的起点是泰迪家,终点则是学校. 这条路中间还有n个路口,从第i-1个路口 ...
- 【JZOJ4745】【NOIP2016提高A组模拟9.3】看电影
题目描述 听说NOIP2016大家都考得不错,于是CCF奖励省常中了 K 张变形金刚5的电影票奖励OI队的同学去看电影.可是省常中OI队的同学们共有 N(N >= K)人.于是机智的你想到了一个 ...
- es安装遇到的问题
问题1: es一闪即逝的问题?java的jdk环境变量没有配置好, JAVA_HOME没有配置好 必须在系统变量里面添加JAVA_HOME: C:\Program Files\Java\jre1.8. ...
- 大数据技术之Zookeeper
第1章 Zookeeper入门 1.1 概述 Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目. 1.2 特点 1.3 数据结构 1.4 应用场景 提供的服务包括:统 ...
- SSH applicationContext.xml import异常
近期在项目上,遇到了一个问题.在配置applicationContext.xml使用<import>标签引入其他的xml文件时,导致项目启动时过慢.有时还会引起启动异常.后来查到是xml文 ...
- 详解 CALayer 和 UIView 的区别和联系
http://www.cocoachina.com/ios/20150828/13244.html 作者:@武蕴牛x 授权本站转载. 前言 前面发了一篇iOS 面试的文章,在说到 UIView 和 C ...
- Effective C++: 04设计与声明
18:让接口容易被正确使用,不易被误用 1:理想上,如果客户企图使用某个接口而却没有获得他所预期的行为,这个代码不该通过编译:如果代码通过了编译,它的作为就该是客户所想要的. 2:许多客户端的错误可以 ...
- 条件变量用例--解锁与signal的顺序问题
我们知道,当调用signal/broadcast唤醒等待条件变量的其他线程时,既可以在加锁的情况下调用signal/broadcast,也可以在解锁的情况下调用. 那么,到底哪种情况更好呢?man手册 ...