涂色PAINT:区间dp
https://ac.nowcoder.com/acm/problem/19909
思路:和取数游戏一样设置dp状态。
设置状态: 表示区间涂[i,j]需要的最少次数。
状态转移:
如果s[i] = s[j],那么在涂[i+1,j]的时候和在涂[i,j-1]的时候可以一起把s[i]或者s[j]涂上。所以
如果s[i] != s[j],分成两段来求,那么我们枚举[i,j]里面的每个点,假设为k,那么
赋初值:当i=j的时候dp[i][j] = 1.
#include <bits/stdc++.h>
#define ull unsigned long long
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 10007;
const int N = 2e5+7;
const int ds = 1e8+7;
const double PI = 3.141592653589793238462643383;
using namespace std;
char s[55];
int dp[555][555];
void solve() {
int n;
cin >> s;
n = strlen(s);
for(int i = 0; i < n*10; i++)
for(int j = 0; j < n*10; j++) dp[i][j] = 1e9;
for(int i = n-1; i >= 0; i--){
for(int j = i; j < n; j++){
if(i == j) dp[i][j] = 1;
else{
if(s[i] == s[j]) dp[i][j] = min(dp[i+1][j],dp[i][j-1]);
else{
for(int k = i; k < j; k++){
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
}
}
//cout << i << ' ' << j << " " << dp[i][j] << endl;
}
}
cout << dp[0][n-1] << endl;
}
int main() {
// int t;
// scanf("%d",&t);
// while(t--)
solve();
return 0;
}