HDU 2476 区间DP-刷字符问题-思维考察

区间DP-刷字符问题-思维考察

翻译了一下这个题,一看还是有点难以入手,标明了是区间DP问题,但是如何DP呢

来捋一捋思路吧

dp[i][j]肯定是从i刷到j所要的次数但是它的i和j是s1串还是s2串呢,怎么能把两个串结合起来考虑呢,这是一个问题,它的转移方程是什么呢

没有想到先去考虑母串的情况

是啊dp[i][j]用来分析母串确实好做一些,从i到j的刷去次数初始赋值dp[i][j] = dp[i+1][j] + 1 直接暴力,然后在寻找中间有没有和i指向的当前这个元素相同的值,如果有的话就可以优化去见了没有的话,就是按照暴力的方法来进行

所以也可以知道对i的遍历我们要你序遍历才可以

这里对k循环的时候要注意是针对第i个元素的优化操作,具体看代码注释

memset(dp,0,sizeof(dp));

        for(int j = 0;j < len;j++)//尾巴
        {
            for(int i = j;i >= 0;i--)
            {
                dp[i][j] = dp[i + 1][j] + 1;//先一个一个暴力刷
                //这里针对的第i个元素
                for(int k = i+1;k <= j;k++)
                {
                    if(s2[i] == s2[k])//因为有相同的了嘛可以拼起来刷了所以这里考虑的i不刷
                        dp[i][j] = min(dp[i][j],dp[i+1][k] + dp[k+1][j]);
                }
            }
        }

 接下来就是结合s1寻找最优解了

先初始化一波

        for(int i = 0;i < len;i++)
            ans[i] = dp[0][i];

 然后再遍历一遍,存在相等的好办,ans[i] = ans[i-1];,表示这个可以不染

对于不相等的位置,尝试找一个间断点,去寻找最小染法

 for(int i = 0;i < len;i++)
        {
            if(s1[i] == s2[i])
                ans[i] = ans[i-1];
            else
            {
                for(int j = 0;j < i;j++)
                {
                    ans[i] = min(ans[i],ans[j] + dp[j+1][i]);
                }
            }
        }

 

这种情况只能说,能理解代码了但是自己想确实没有能轻松相出一个比较有效的解决办法

 

posted @ 2018-07-24 15:57  Butterflier  阅读(257)  评论(0编辑  收藏  举报