HDU - 2476
思路:分解问题,先考虑从一个空串染色成 B串的最小花费 ,区间DP可以解决这个问题
具体的就是,当 str [ l ] = = str [ r ]时 dp [ L ] [ R ] = min (dp [ L + 1] [ R ],dp [ L ] [ R-1 ] )
其他情况可以选择任意一个断点 tmp = min ( tmp , dfs ( l ,k ) + dfs ( k+1 , r ) );
接下来就是第二步 现在A串不是空串 ,但然把它当做空串去染是没有问题的,
但是现在有可能出现 A串有些部分与B串是相同的,所以会减少一些花费,定义 f 为到此为止由A转化为B的最小花费
那么我们就一个一个字符的来看,min ( f [ j ] + dp [ j ] [ i ] ) ( j < i ),当 A [ i ] = = B [ i ] 时多一个选择 f [ i - 1 ] 直接转移过来
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define maxn 123 int ans,len,f[maxn]; int dp[maxn][maxn],n; char str[maxn],son[maxn]; int dfs(int l,int r) { if(l==r) dp[l][r]=1; if(dp[l][r]!=-1)return dp[l][r]; int tmp=inf; if(str[l]==str[r]) tmp=min(dfs(l,r-1),dfs(l+1,r)); else for(int k=l; k<r; k++) tmp=min(tmp,dfs(l,k)+dfs(k+1,r)); return dp[l][r]=tmp; } int main() { while(~scanf("%s%s",son,str)) { memset(dp,-1,sizeof(dp)); int len=strlen(str); dfs(0,len-1); for(int i=0; i<len; i++) { f[i]=dp[0][i]; for(int j=0; j<i; j++) f[i]=min(f[j]+dp[j+1][i],f[i]); if(son[i]==str[i]) if(i==0)f[i]=0; else f[i]=min(f[i],f[i-1]); } printf("%d ",f[len-1]); } return 0; }