给定两个长度分别为m和n的,元素均为整数的数组a[1..m]和b[1..n],有两种操作:
求使得这两个数组变得完全相同(需要考虑次序,即对于所有的i,有a[i] == b[i])的最小总花费。(已知m, n <= 2000,数组元素的绝对值<=10000)
如果将第2种操作中的花费改为1,又可以怎么做?
对于原问题,如果数组相同的定义不在乎次序的话(下标位置可交换),例如[1,2,3]和[2,1,3]这两个数组也是相同的,那么假设我们的a数组一定是比b数组长的(如果不是的话,交换一下次序就好了),那么说明我们一定会删除a数组m-n个元素
我目前能想到的做法是一种很慢的DP算法:
对于两个数组a和b,把它们操作成一样的最小花费记为min_cost(a, b).
①如果a和b一样长,
一种选择是一个不删,直接把a[i]一个一个调整成b[i],花费为sum_i |a[i] - b[i]|;
另一种选择是删掉a中的某一个元素a[i]得到新数组aa,再删掉b中的某一个元素b[j]得到新数组bb,此时aa和bb等长,可以递归调用min_cost,此时的花费为|a[i]| + |b[j]| + min_cost(aa, bb)
最终写出的状态转移方程为:
min_cost(a, b) = min(sum_i |a[i] - b[i]|, |a[i]| + |b[j]| + min_cost(a删掉a[i], b删掉b[j]) 对于所有的i和j)
②如果a和b不一样长,不妨让a长于b,那么a中一定有元素需要扔掉,于是可以写出:
min_cost(a, b) = min_i (|a[i]| + min_cost(a删掉a[i], b))
这样就可以写出暴力的分治法了。然后对算过的min_cost(a, b)做记录,就是一种备忘录式DP算法,但这个算法还是太慢了。