【Link】:

【Description】



给你两个序列,都由大写字母组成;

每次,把两个序列中的一个的开头字母加在字符串的尾端,然后在那个序列中删掉那个开头字母;

最后得到一个字符串;

这个字符串显然后很多种;

让你找所有字母的L(C)的和的最小值;

L(c)是某个字母在最后的那个字符串中出现的结尾位置和开始位置的差值;

【Solution】



设f[i][j]表示第一个序列1..i全都移除掉了,第二个序列1..j全都移除掉了的最小L(c)和;

这里不能直接算出某个字母的L(C)值,但是能一步一步地累加,比如,你新加了一个字母x,然后在此之前,已有的字符串里面,有字母a,且还有未加入的字母a;

则L(a)的值可以肯定会递增1了;

则可以写出转移方程

f[i][j]=min(f[i][j],f[i−1][j]+cnt[i−1][j])

f[i][j]=min(f[i][j],f[i][j−1]+cnt[i][j−1]);

这里的cnt[i][j]表示第一个序列前i个字母移出去了,第二个序列前j个字母移出去了所形成的字符串,有多少个字母已经出现了,但是还没有全部出现;

为了获取这个cnt数组;

可以先获取,每个字母在这两个序列中第一次出现最后一次出现的位置;

然后对于枚举的i和j;

看看每个字母是不是在这个情况下出现了;

这样就能获得cnt数组;



【NumberOf WA】



4



【Reviw】



用memset会莫名的TLE;

改成循环就过了



【Code】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 5e3;
const int INF = 0x3f3f3f3f; int dp[N+100][N+100],n,m,cnt[N+100][N+100];
pii a1[27],a2[27];
char s1[N+100],s2[N+100]; int main(){
//Open();
//Close();
int T;
scanf("%d",&T);
while (T--){
scanf("%s",s1+1);
scanf("%s",s2+1);
n = strlen(s1+1),m = strlen(s2+1); rep1(i,1,26) a1[i].fi = a1[i].se = a2[i].fi = a2[i].se = 0; //第一次出现
rep1(i,1,n){
int t = s1[i]-'A'+1;
if (a1[t].fi==0) a1[t].fi = i;
}
rep1(i,1,m){
int t = s2[i]-'A'+1;
if (a2[t].fi==0) a2[t].fi = i;
} //最后一次出现
rep2(i,n,1){
int t = s1[i]-'A'+1;
if (a1[t].se==0) a1[t].se = i;
}
rep2(i,m,1){
int t = s2[i]-'A'+1;
if (a2[t].se==0) a2[t].se = i;
}
rep1(i,0,n)
rep1(j,0,m){
int temp = 26;
rep1(k,1,26){
if (a1[k].fi == 0 && a2[k].fi==0){
temp--;
continue;
}
if (a1[k].fi!=0 && a2[k].se==0){
if (i<a1[k].fi){
temp--;
continue;
}
if (a1[k].se<=i){
temp--;
continue;
}
}
if (a1[k].fi==0 && a2[k].se!=0){
if (j<a2[k].fi){
temp--;
continue;
}
if (a2[k].se<=j){
temp--;
continue;
}
}
if (a1[k].fi!=0 && a2[k].fi!=0){
if (i<a1[k].fi && j<a2[k].fi){
temp--;
continue;
}
if (a1[k].se<=i && a2[k].se<=j){
temp--;
continue;
}
}
}
cnt[i][j] = temp;
}
rep1(i,0,n)
rep1(j,0,m)
dp[i][j] = INF;
dp[0][0] = 0;
rep1(i,0,n)
rep1(j,0,m){
if (i-1 >= 0){
dp[i][j] = min(dp[i][j],dp[i-1][j] + cnt[i-1][j]);
}
if (j-1 >= 0){
dp[i][j] = min(dp[i][j],dp[i][j-1] + cnt[i][j-1]);
}
}
cout << dp[n][m] << endl;
}
return 0;
}

【Uva 1625】Color Length的更多相关文章

  1. 【巧妙算法系列】【Uva 11464】 - Even Parity 偶数矩阵

    偶数矩阵(Even Parity, UVa 11464) 给你一个n×n的01矩阵(每个元素非0即1),你的任务是把尽量少的0变成1,使得每个元素的上.下.左.右的元素(如果存在的话)之和均为偶数.比 ...

  2. 【贪心+中位数】【UVa 11300】 分金币

    (解方程建模+中位数求最短累积位移) 分金币(Spreading the Wealth, UVa 11300) 圆桌旁坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一 ...

  3. 【UVa 10881】Piotr's Ants

    Piotr's Ants Porsition:Uva 10881 白书P9 中文改编题:[T^T][FJUT]第二届新生赛真S题地震了 "One thing is for certain: ...

  4. 【UVa 116】Unidirectional TSP

    [Link]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  5. 【UVa 1347】Tour

    [Link]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  6. 【UVA 437】The Tower of Babylon(记忆化搜索写法)

    [题目链接]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  7. 【uva 1025】A Spy in the Metro

    [题目链接]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  8. 【Uva 1627】Team them up!

    [Link]: [Description] 给你n个人; 有一些人之间有认识关系 a认识b,b不一定认识a 让你把这n个人分成两组 使得这两组中的每一组: 组内的人与人之间都相互认识. 并且,使得两组 ...

  9. 【Uva 11080】Place the Guards

    [Link]: [Description] 一些城市,之间有道路相连,现在要安放警卫,警卫能看守到当前点周围的边,一条边只能有一个警卫看守,问是否有方案,如果有最少放几个警卫. [Solution] ...

随机推荐

  1. 蓝牙压力測试报抛android.os.TransactionTooLargeException异常分析总结

    1.从main日志中找到异常点,例如以下: 08-20 11:05:19.754 5023 5023 E AndroidRuntime: FATAL EXCEPTION: main 08-20 11: ...

  2. C++学习第一天--编译命令

    前一个月的时间主要是在捯饬自己的ubuntu vim环境,昨天终于都搞好了,从今天开始,学习C++.至于为什么学习C++,其实很大一部分原因还是因为自己喜欢vim,又听说vim对C++的支持还不错,所 ...

  3. iOS代码添加视图约束

    项目要做这样一个效果的启动页. 考虑到版本号是会不断变更的,因此采用动画效果启动页,让版本号动态加载iOS启动页动画效果 - 简书 考虑到屏幕适配问题,因此采用代码对视图添加约束.在添加约束的过程中遇 ...

  4. thinkPHP的模板是做什么用的

    thinkPHP的模板是做什么用的 问题 为什么PHP中ThinkPHP有做类似模板引擎的东西?smarty也是?这些到底有何用? 我是真没发现它们的用处在哪里?分离了前端和PHP的依赖?HTML文件 ...

  5. Python: PS 滤镜--碎片特效

    本文用 Python 实现 PS 滤镜中的碎片特效,这个特效简单来说就是将图像在 上,下,左,右 四个方向做平移,然后将四个方向的平移的图像叠加起来做平均.具体的效果图可以参考之前的博客 http:/ ...

  6. BZOJ 2124 线段树维护hash值

    思路: http://blog.csdn.net/wzq_QwQ/article/details/47152909 (代码也是抄的他的) 自己写得垃圾线段树怎么都过不了 隔了两个月 再写 再挂 又隔了 ...

  7. Google Codejam 2016 Round1A Problem C BFFs 简单图论

    链接 Google Codejam 2016 Round1A Problem C BFFs 题意 n个小朋友要坐成一个圈.每个小朋友心中都有一个Best Friend Forever.要保证每个人的左 ...

  8. Kali linux 2016.2(Rolling)中metasploit的搜集特定网站的目录结构

    不多说,直接上干货! parent directory site: testfire.net 至于这里怎么FQ,很简单,请见我下面的博客! kali 2.0安装 lantern(成功FQ) shado ...

  9. 虚拟主机TOMCAT配置

    在tomcat中添加虚拟主机: 编辑"tomcat\conf\server.xml",在"<Engine></Engine>"元素中新加 ...

  10. <Sicily>数字反转

    一.题目描述 给定一个整数,请将该数各个位上数字反转得到一个新数.新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例2). 二.输入 输入共 1 行, ...