动态规划(模型转换):uvaoj 1625 Color Length

时间:2022-10-10 04:49:00

[PDF Link]题目点这里

  这道题一眼就是动态规划,然而貌似并不好做。

  如果不转换模型,状态是难以处理的。

  巧妙地转化:不直接求一种字母头尾距离,而是拆开放到状态中。

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
char s1[maxn],s2[maxn];
int B1[],E1[],B2[],E2[];
int dp[maxn][maxn];
int add[maxn][maxn];
int main(){
int T,len1,len2;
scanf("%d",&T);
while(T--){
scanf("%s",s1+);
scanf("%s",s2+);
len1=strlen(s1+);
len2=strlen(s2+);
memset(B1,,sizeof(B1));
memset(E1,-,sizeof(E1));
memset(B2,,sizeof(B2));
memset(E2,-,sizeof(E2));
for(int i=;i<=len1;i++){
s1[i]-='A';
if(B1[s1[i]]>len1)B1[s1[i]]=i;
E1[s1[i]]=i;
} for(int i=;i<=len2;i++){
s2[i]-='A';
if(B2[s2[i]]>len2)B2[s2[i]]=i;
E2[s2[i]]=i;
} for(int i=;i<=len1;i++)
for(int j=;j<=len2;j++){
if(i==j&&i==)continue;
if(!i||j&&dp[i][j-]+add[i][j-]<=dp[i-][j]+add[i-][j]){
dp[i][j]=dp[i][j-]+add[i][j-];
add[i][j]=add[i][j-];
if(B2[s2[j]]==j&&B1[s2[j]]>i)
add[i][j]++;
if(E2[s2[j]]==j&&E1[s2[j]]<=i)
add[i][j]--;
}
if(!j||i&&dp[i][j-]+add[i][j-]>dp[i-][j]+add[i-][j]){
dp[i][j]=dp[i-][j]+add[i-][j];
add[i][j]=add[i-][j];
if(B1[s1[i]]==i&&B2[s1[i]]>j)
add[i][j]++;
if(E1[s1[i]]==i&&E2[s1[i]]<=j)
add[i][j]--;
}
}
printf("%d\n",dp[len1][len2]);
}
return ;
}