随手练——Uva-11584 划分成回文串(区间DP)
思路:dp[i]代表到第i位的最小值,枚举它的前几位,求出最小值。
转移方程:dp[ i ] = min(dp[ i ], dp[ j - 1 ] + 1 ) ;
本来觉得,代码加深部分可以提前break,其实不行,有些特例,比如:oioooo
oio ooo是最少的,两个;提前break的话,会判断成oi oooo,三个。
最开始用string写的,一直超时,改成char数组才过的了。
#include <iostream> #include <string.h> #include <algorithm> #include <string> using namespace std; char arr[1010]; int dp[1010]; int res = 0; bool check(int i,int j) { while (i < j) { if (arr[i] != arr[j])return false; i++, j--; } return true; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%s", arr); memset(dp, 0, sizeof(dp)); dp[0] = 0; for (int i = 1; i <= strlen(arr); i++) { dp[i] = i; for (int j = 1; j <= i; j++) { if (check(j - 1, i - 1)) { dp[i] = min(dp[i], dp[j - 1] + 1); } } } printf("%d\n", dp[strlen(arr)]); } return 0; }