给你一个序列c[],每个位置有一个数值代表颜色
初始选定某一个起始位置,
可以将包含起始位置连续相同颜色段换成任意颜色,
换一次cost+1,
问最后所有颜色相同时,cost最小为多少
https://blog.csdn.net/toohandsomeIeaseId/article/details/86983883
很经典的区间dp问题
大概就是删啊变啊最小cost那种
然而区间dp做的还是不够多
本题注意到合并之后[l,r]的颜色只能与a[l]或a[r]相同
这就可以dp了,只有两种转移状态
dp[l][r][0]代表当前颜色为a[l]的最小cost
dp[l][r][1]代表当前颜色为a[r]的最小cost
[l,r-1]与a[r]合并的时候,只能变成a[r]的颜色,去看[l,r-1]的颜色是a[l]还是a[r-1]即可
同理[l+1,r]与a[l]合并的时候,只能变成a[l]的颜色,去看[l+1,r]的颜色是a[l+1]还是a[r]即可
dp[l][r][1]=min(dp[l][r-1][0]+(a[l]!=a[r]),dp[l][r-1][1]+(a[r-1]!=a[r])) 变成r的颜色
dp[l][r][0]=min(dp[l+1][r][0]+(a[l]!=a[l+1]),dp[l+1][r][1]+(a[l]!=a[r])) 变成l的颜色
看个人喜好,有三种不同的写法,
前两种是区间长度的扩张,[l,r]总是从[l,r-1]和[l+1,r]的最优中得来
而最后一种是当前状态向外两种状态的拓展,[l,r]可以向[l-1,r]和[l,r+1]转移
个人喜欢第一种,枚举长度len,枚举左端点l,比较套路
第二种则是固定右端点,每次从右往左扫,[l,r]总是从[l,r-1]和[l+1,r]得来,
[l,r-1]在上一轮r已经得出,而[l+1][r]在本轮r的上一内循环l也已得出,故可行
#include
#include
#include
#include
#include
#include
#include