【动态规划】[UVa1625]Color Length
分析一下发现如果每一次放进去一个新,它就会对所有覆盖这个点的所有颜色的L加1那么另
int add(int x, int y) {
int cnt = 0;
for(int i=0;i<26;i++){
if(pos[i][1] <= x && pos2[i][1] <= y) continue;
if(pos[i][0] > x && pos2[i][0] > y) continue;
if(pos[i][0] > x && pos2[i][0] == -1) continue;
if(pos2[i][0] > y && pos[i][0] == -1) continue;
cnt++;
}
return cnt;
}
之前可以先预处理一下每一种颜色在每一段中的起始位置和结束位置
void Init(){
memset(pos, -1, sizeof pos);
memset(pos2, -1, sizeof pos2);
int len = strlen(s1+1);
for(int i=1;i<=len;i++)
pos[s1[i]-'A'][1] = i;
for(int i=len;i>=1;i--)
pos[s1[i]-'A'][0] = i;
len = strlen(s2+1);
for(int i=1;i<=len;i++)
pos2[s2[i]-'A'][1] = i;
for(int i=len;i>=1;i--)
pos2[s2[i]-'A'][0] = i;
}
然后很容易发现
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 100000;
int pos[26][2], pos2[26][2];
char s1[MAXN+10], s2[MAXN+10];
void Init(){
memset(pos, -1, sizeof pos);
memset(pos2, -1, sizeof pos2);
int len = strlen(s1+1);
for(int i=1;i<=len;i++)
pos[s1[i]-'A'][1] = i;
for(int i=len;i>=1;i--)
pos[s1[i]-'A'][0] = i;
len = strlen(s2+1);
for(int i=1;i<=len;i++)
pos2[s2[i]-'A'][1] = i;
for(int i=len;i>=1;i--)
pos2[s2[i]-'A'][0] = i;
}
int add(int x, int y) {
int cnt = 0;
for(int i=0;i<26;i++){
if(pos[i][1] <= x && pos2[i][1] <= y) continue;
if(pos[i][0] > x && pos2[i][0] > y) continue;
if(pos[i][0] > x && pos2[i][0] == -1) continue;
if(pos2[i][0] > y && pos[i][0] == -1) continue;
cnt++;
}
return cnt;
}
const int INF = 999999999;
int dp[2][MAXN+5];
int solve(){
memset(dp, 0, sizeof dp);
int now = 0, len1 = strlen(s1+1), len2 = strlen(s2+1);
for(int i=1;i<=len2;i++) dp[now][i] = INF;
for(int i=0;i<=len1;i++){
now ^= 1;
for(int j=0;j<=len2;j++)
dp[now][j] = min(((j-1)>=0?dp[now][j-1]:INF), dp[now^1][j]) + add(i, j);
}
return dp[now][len2];
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%s%s", s1+1, s2+1);
Init();
printf("%d\n", solve());
}
}