洛谷 P4170 [CQOI2007]涂色(区间dp)
传送门
解题思路
dp[i][j]表示把区间[i...j]涂成目标颜色的最少步骤。
当s[i]==s[j]时,我们可以发现,在涂第i个格子时,我们可以多涂上一格,将第j格涂上;同理,可以在涂第j个格子时,多图一个格子,把第i格涂上。所以就可以从dp[i+1][j]和dp[i][j-1]转移而来。
对于一般情况,我们能做到的只有把这个区间分成两部分,枚举断点k,求两部分的和,取min值。
AC代码
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 int dp[55][55]; 7 string s; 8 int main() 9 { 10 cin>>s; 11 memset(dp,0x3f,sizeof(dp)); 12 for(int i=0;i<s.length();i++) dp[i][i]=1; 13 for(int len=2;len<=s.length();len++){ 14 for(int i=0;i<s.length();i++){ 15 int j=i+len-1; 16 if(j>=s.length()) break; 17 if(s[i]==s[j]) dp[i][j]=min(dp[i+1][j],dp[i][j-1]); 18 for(int k=i;k<j;k++){ 19 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); 20 } 21 } 22 } 23 cout<<dp[0][s.length()-1]; 24 return 0; 25 }