1 /* 2 3 题意: T组测试用例,每例不超过1000小写字母, 4 三种操作把它变成回文, 5 1.任意位置删除一个 6 2.任意位置添加一个 7 3.任意位置替换一个 8 输出最小操作数 。 9 10 定义 dp[l][r] 为 l 到 r 要多少次操作,因为添加和删除效果一样,就只用删除和替换。 11 如果str[l]==str[r] 那么 dp[l][r]=dfs(l+1,r-1); 12 否则 dp[l][r]=min (dfs(l+1,r),dfs(l,r+1),dfs(l+1,r-1) ); 13 这也是看了其他大神的做法后才造的,再接再厉,争取自己想到 o(╯□╰)o 14 15 */ 16 #include<cstdio> 17 #include<algorithm> 18 #include<cstring> 19 using namespace std; 20 int dp[1010][1010]; 21 char str[1010]; 22 int dfs(int l,int r) 23 { 24 if(dp[l][r]!=-1) return dp[l][r]; 25 if(l==r || l==r+1) return dp[l][r]=0; 26 if(str[l]==str[r]) dp[l][r]=dfs(l+1,r-1); 27 else 28 { 29 dp[l][r]=dfs(l+1,r); 30 int x=dfs(l,r-1); 31 dp[l][r]=(dp[l][r]<x)?dp[l][r]:x; 32 x=dfs(l+1,r-1); 33 dp[l][r]=(dp[l][r]<x)?dp[l][r]:x; 34 dp[l][r]+=1; 35 } 36 return dp[l][r]; 37 } 38 int main() 39 { 40 int t,cnt=0; 41 scanf("%d",&t); 42 getchar(); 43 while(t--) 44 { 45 scanf("%s",str); 46 memset(dp,-1,sizeof(dp)); 47 int len=strlen(str); 48 printf("Case %d: %d ",++cnt,dfs(0,len-1)); 49 } 50 }
= =| N久之后再写......
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1010; const int INF = 0x3f3f3f3f; int d[maxn][maxn]; char s[maxn]; int dfs(int l, int r) { if (d[l][r] != -1) return d[l][r]; if (l >= r) return d[l][r] = 0; if(s[l] == s[r]) d[l][r] = dfs (l+1, r-1); else { d[l][r] = dfs (l+1, r); d[l][r] = min (d[l][r], dfs (l, r-1)); d[l][r] = min (d[l][r], dfs (l+1, r-1)); d[l][r] += 1; } return d[l][r]; } int main() { int t, cas = 1; scanf ("%d", &t); getchar(); while (t --) { scanf ("%s", s); memset (d, -1, sizeof (d)); int r = strlen (s); int ans = dfs (0,r-1); printf ("Case %d: %d ", cas++, ans); } return 0; }