hdoj 2476 String painter(dp)

来源:互联网 发布:mac魅可香港官网 编辑:程序博客网 时间:2024/05/29 11:16

【题目大意】:给出两段字符串,要将a串变为b串,每次可以将其联系的一个子串改成任意的一个字母,问最少需要操作多少次。


【解题思路】:dp。去年的暑假,遇到一道类似的问题,是21个点,队友用状态压缩搜索过了,我用贪心也水了过去。但是这一次,是100,没办法搜索,贪心也失效了。

                            其实这道题目一看就是一个明显的区间dp。

 dp[i][j]=min(dp[i+1][j]+1,dp[i+1][k]+dp[k+1][j]) 表示从i~j要操作多少次才能满足题设。

                            dp_ans[i]=min(dp_ans[j]+dp[j+1][i])  表示0刷到i需要多少次操作


【代码】:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <cmath>#include <string>#include <cctype>#include <map>#include <iomanip>                   using namespace std;                   #define eps 1e-8#define pi acos(-1.0)#define inf 1<<30#define linf 1LL<<60#define pb push_back#define lc(x) (x << 1)#define rc(x) (x << 1 | 1)#define lowbit(x) (x & (-x))#define ll long longstring s1,s2;int minn,len;int dp[200][200],ans[200];int main() {    while (cin >> s1){        cin >> s2;        len=s1.size();        memset(dp,0,sizeof(dp));        for (int i=0; i<len; i++) dp[i][i]=1;        for (int j=0; j<len; j++) {            for (int i=j-1; i>=0; i--) {                dp[i][j]=dp[i+1][j]+1;                for (int k=i+1; k<=j; k++) {                    if (s2[i]==s2[k]) {                        dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);                                                }                }            }        }        for (int i=0; i<len; i++) {            ans[i]=dp[0][i];            if (s1[i]==s2[i]) {                if (i==0) ans[i]=0;                else ans[i]=ans[i-1];            }            else {                for (int j=0; j<i; j++)                     ans[i]=min(ans[i],ans[j]+dp[j+1][i]);            }        }        printf("%d\n", ans[len-1]);    }    return 0;}


原创粉丝点击