【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. JavaScript中的Array对象方法调用

    方法concat for  循环与for in 循环 <html> <head> <script type="text/javascript"> ...

  2. zzulioj--1787--生活危机(vector+dfs 好题)

    1787: 生化危机 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 97  Solved: 29 SubmitStatusWeb Board Desc ...

  3. 7.stack

    #include <iostream> #include <stack> #include <algorithm> #include <list> #i ...

  4. LINQ返回DataTable类型 list转dataset 转换为JSON对象

    using System.Web.Script.Serialization; using System.Collections.Generic; using System.Reflection; us ...

  5. c#DataGridView复制粘贴删除功能

    //可在dgv中复制.剪切.粘贴.删除数据 /// <summary> /// DataGridView复制 /// </summary> /// <param name ...

  6. Linux VNC Viewer客户端

    1.realvnc-vnc-viewer 这个我感觉应该是做的做好用的VNC Viewer客户端了,毕竟是商业软件,但是VNC Viewer客户端是免费的.使用前 需要到官网下载对应发行版的软件包进行 ...

  7. Linux下的压缩与解压缩

    1 .gz 1)压缩 root@xiaohuang-virtual-machine:/home/xiaohuang/桌面/hellow/hellow# gzip 2.txt 3.txt root@xi ...

  8. python IO编程-序列化

    原文链接:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143192607 ...

  9. 钩子(hooks)—webhook-使用钩子自动触发部署

    钩子(hooks)-webhook http://fighter.blog.51cto.com/1318618/1670667 https://www.lovelucy.info/auto-deplo ...

  10. 八 rowkey设计 几种方法

    简单来讲,rowkey就是 KeyValue 中的key     rowkey设计之 尽量散列设计 RowKey         如第三部分第六中讲到,如果数据都是有序的存储到一个特定的范围内,将会存 ...