UVA11584-Partitioning by Palindromes(動態規劃基礎)
Accept: 1326 Submit: 7151
Time Limit: 3000 mSec
Problem Description
Input
Your program is to read from standard input. The input consists of T test cases. The number of test cases T is given in the ?rst line of the input. Each test case consists of two lines. In the ?rst line, a character string of length n (1 ≤ n ≤ 5,000) that is the color information of the cars in one lane before merging is given. In the second line, a character string of length m (1 ≤ m ≤ 5,000) that is the color information of the cars in the other lane is given. Every color is represented as an uppercase letter in English, hence the number of colors is less than or equal to 26.
Output
Your program is to read from standard input. Print exactly one line for each test case. The line should contain the sum of color lengths after merging the cars in the two lanes optimally as described above. The following shows sample input and output for two test cases.Sample Input
AAABBCY
ABBBCDEEY
GBBY
YRRGB
Sample Output
10
12
題解:這個題真是醉了,自己想狀態,總有後效性,想了很久還是看了lrj的思路,恍然大悟,還是很有啟發性的,局部有後效性,但是整體上沒有,不失為以後考慮問題的一個思路,本以為這個題已經沒啥說的了,寫的時候才發現細節太多了,if 、else寫到惡心,還一直有不對的地方,後來在不斷調試過程中發現問題主要出現在只出現在一個字符串中的字符上,想出了一個很好的解決方案,就是將第一次出現的地方初始化為INF,沒出現就代表著出現在無窮遠處,將最後出現的地方初始化為0,沒出現就代表著在最前面結束,有了這個初始化就好寫很多,調一調就好,dp相對轉移起來還是比較簡單的,方程見代碼。
1 #include <bits/stdc++.h> 2 //#define DE 3 4 using namespace std; 5 6 const int maxn = 5000 + 10; 7 const int kind = 256; 8 const int INF = 0x3f3f3f3f; 9 10 char a[maxn], b[maxn]; 11 int num[maxn][maxn], dp[maxn][maxn]; 12 int st[2][kind], tail[2][kind]; 13 int alen, blen; 14 15 void pre_management(int p, char *str) { 16 int len = strlen(str + 1); 17 for (int i = 1; i <= len; i++) { 18 if (st[p][str[i]] == INF) st[p][str[i]] = i; 19 } 20 for (int i = len; i >= 1; i--) { 21 if (tail[p][str[i]] == 0) tail[p][str[i]] = i; 22 } 23 } 24 25 void init() { 26 memset(st, INF, sizeof(st)); 27 memset(tail, 0, sizeof(tail)); 28 pre_management(0, a); pre_management(1, b); 29 30 int cnt = 0; 31 for (int i = 0; i <= alen; i++) { 32 for (int j = 0; j <= blen; j++) { 33 if (i) { 34 num[i][j] = num[i - 1][j]; 35 if (i == st[0][a[i]] && j < st[1][a[i]]) num[i][j]++; 36 if (i == tail[0][a[i]] && j >= tail[1][a[i]]) num[i][j]--; 37 } 38 if (j) { 39 num[i][j] = num[i][j - 1]; 40 if (j == st[1][b[j]] && i < st[0][b[j]]) num[i][j]++; 41 if (j == tail[1][b[j]] && i >= tail[0][b[j]]) num[i][j]--; 42 } 43 } 44 } 45 } 46 47 void solve() { 48 dp[0][0] = 0; 49 for (int i = 0; i <= alen; i++) { 50 for (int j = 0; j <= blen; j++) { 51 if (!i && !j) continue; 52 dp[i][j] = INF; 53 if (i) { 54 dp[i][j] = min(dp[i - 1][j] + num[i][j], dp[i][j]); 55 } 56 if (j) { 57 dp[i][j] = min(dp[i][j - 1] + num[i][j], dp[i][j]); 58 } 59 } 60 } 61 printf("%d\n", dp[alen][blen]); 62 } 63 64 int main() 65 { 66 //freopen("input.txt", "r", stdin); 67 int iCase; 68 scanf("%d", &iCase); 69 while (iCase--) { 70 scanf("%s%s", a + 1, b + 1); 71 alen = strlen(a + 1), blen = strlen(b + 1); 72 init(); 73 solve(); 74 #ifdef DE 75 for (int i = 1; i <= alen; i++) { 76 for (int j = 1; j <= blen; j++) { 77 printf("num[%d][%d]: %d ", i, j, num[i][j]); 78 } 79 printf("\n"); 80 } 81 for (int i = 1; i <= alen; i++) { 82 for (int j = 1; j <= blen; j++) { 83 printf("%d ", num[i][j]); 84 } 85 printf("\n"); 86 } 87 #endif // DE 88 } 89 return 0; 90 }
UVA11584-Partitioning by Palindromes(動態規劃基礎)