您的位置:首页 > 其它

UVa1625 Color Length

2016-10-28 13:49 417 查看
UVa1625 - Vjudge

题目大意:

将两个颜色序列按照顺序合并成一个序列,使每种颜色的最大位置和最小位置之差的和最小。

题解:

f[i][j]表示两个序列分别移走了i和j个元素,还需要多少费用。记录已经开始但是还未结束的颜色的数量为tmp,则f[i][j] = tmp + min( f[i-1][j], f[i][j-1] )。tmp可以通过预处理每个颜色在两个序列中的开始位置和结束位置得到。

// UVa 1625 By KikiDMW
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int N = 5000 + 10, L = 30, inf = 0x3f3f3f3f;

int f

, c

, t, n, m;
int sta[L], stb[L], eda[L], edb[L];
char s1
, s2
;

inline void in(int &ret);
inline void in(ll &ret);

void init(){
scanf("%s%s", s1+1, s2+1);
for(int i = 0; i < 26; i++) sta[i] = stb[i] = inf, eda[i] = edb[i] = -inf;
}
void work(){
while(t--){
init();
n = strlen(s1+1); m = strlen(s2+1);
for(int i = 1; i <= n; i++){
if(sta[s1[i]-'A'] == inf) sta[s1[i]-'A'] = i;
eda[s1[i]-'A'] = i;
}
for(int i = 1; i <= m; i++){
if(stb[s2[i]-'A'] == inf) stb[s2[i]-'A'] = i;
edb[s2[i]-'A'] = i;
}
for(int i = 1; i <= n+1; i++){
for(int j = 1; j <= m+1; j++){
f[i][j] = 0;
for(int k = 0; k < 26; k++)
if((sta[k] < i || stb[k] < j) && (i <= eda[k] || j <= edb[k]))
f[i][j]++;
if(i == 1 && j == 1) continue;
else if(j == 1) f[i][j] += f[i-1][j];
else if(i == 1) f[i][j] += f[i][j-1];
else f[i][j] += min(f[i-1][j], f[i][j-1]);
}
}
printf("%d\n", f[n+1][m+1]);
}
}

int main(){
in(t);
work();
return 0;
}
inline void in(int &ret){
ret = 0; int f = 1; char ch; ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9'){ ret = ret * 10 + ch - '0'; ch = getchar(); }
ret *= f;
}
inline void in(ll &ret){
ret = 0; ll f = 1; char ch; ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9'){ ret = ret * 10 + ch - '0'; ch = getchar(); }
ret *= f;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: