题意:
给出两个字符串,求把两字符串组成一个字符串使的字符串中的相同字母的最远距离的和最小。
分析:
本题关键在于怎么计算距离和的方法上。dp[i][j]表示处理到长度i的a串,长度j的b串还需要的计算的距离
dp[i][j]=min(dp[i+1][j],dp[i][j+1])+num[i][j](表示组成的串中已出现的字母但未结束的个数,已出现但未结束,随着dp的递推,每个已出现但未结束都会贡献距离,本人的理解)
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define N 5010 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; int dp[N][N],l[30][2],r[30][2],num[N][N],used[N]; char s1[N],s2[N]; void solve(){ for(int i=0;i<26;++i) l[i][0]=l[i][1]=INF; memset(r,-1,sizeof(r)); memset(used,0,sizeof(used)); int l1=strlen(s1); int l2=strlen(s2); for(int i=0;i<l1;++i){ int id=s1[i]-‘A‘; if(!used[id]){ used[id]=1; } if(l[id][0]==INF) l[id][0]=i; r[id][0]=i; } for(int i=0;i<l2;++i){ int id=s2[i]-‘A‘; if(!used[id]){ used[id]=1; } if(l[id][1]==INF) l[id][1]=i; r[id][1]=i; } for(int i=0;i<=l1;++i) for(int j=0;j<=l2;++j) { int tmp=0; for(int k=0;k<26;++k){ if(l[k][0]==INF&&l[k][1]==INF) continue; if(l[k][0]>i-1&&l[k][1]>j-1) continue; if(r[k][0]<=i-1&&r[k][1]<=j-1) continue; tmp++; } num[i][j]=tmp; } dp[l1][l2]=0; for(int i=l2-1;i>=0;--i) dp[l1][i]=dp[l1][i+1]+num[l1][i]; for(int i=l1-1;i>=0;--i) dp[i][l2]=dp[i+1][l2]+num[i][l2]; for(int i=l1-1;i>=0;--i) for(int j=l2-1;j>=0;--j) dp[i][j]=min(dp[i+1][j],dp[i][j+1])+num[i][j]; printf("%d\n",dp[0][0]); } int main() { int t; scanf("%d",&t); while(t--){ scanf("%s%s",s1,s2); solve(); } return 0; }
时间: 2025-01-06 15:48:29