DP算法最大字段和 a[1...n]
找出连续子序列和最大的一个
(曹博的PPT里面看到的)DP算法 最长单调递增(递减)子序列 a[1...n] 王晓东算法书一道习题记得是
找出未必连续的 最长的 单调递增子序列
dp[i]: 表示a[1...i]的最长单调递增子序列,由于是否加一个元素与之前解的最后一个元素大小有关,因此用j记录
dp[i-1]的最优解最后一个元素,
dp[i]=dp[i-1]+1 a[i]>a[j],j记录之前的最后一个元素index
dp[i-1] a[i]<a[j]
但是后来才发现这个DP是错的,举个范例, 1 3 2 2.5 解为1 2 2.5,但是实际上述跑出来是1 3 ,因为后面会因为
比之前的3小而放弃,所有DP有时候模糊写了一个算法,好像是对的,往往是错的。。。。。
正确的算法是O(n^2)的,思路仿照最大字段和,dp[i]不是原问题的子空间最优解,而是包含a[i]在内的子空间的
最优解,然后再遍历一遍 dp[1...n]就是原问题最优解了。
这个是从另一个角度来划分子空间,从解的最有一个元素是那个index的角度,可能的只有1...n
dp[i]=max{dp[x], x<i, a[x]<a[i]}+1
为什么不考虑比a[i]大的a[x]呢?因为定义啊,子空间最后一个元素就是a[i], 如果前面大的话只能放弃a[i], 那么得出的解就不符合定义
这个想想其实挺巧妙的。
另外当时想最大字段和为啥是:
b[j]= max{a[j], b[j-1]+a[j]}, 也即如果前面一个是负的,就全部丢弃,选a[j],否则累加a[j]?
我当时可不可能是 (sum=)a[k...j-1]+a[j] 会更优,k>1? 后来发现不可能, 假设b[j-1] <0, a[j] 较大,如果b[j]里面,有
更优解 a[k...j-1,j] 那么大于a[j] 所以sum a[k...j-1]>0, b[j-1]比存在一个大于0的最优解,与假设矛盾,所以b[j-1]<0
找出连续子序列和最大的一个
(曹博的PPT里面看到的)DP算法 最长单调递增(递减)子序列 a[1...n] 王晓东算法书一道习题记得是
找出未必连续的 最长的 单调递增子序列
dp[i]: 表示a[1...i]的最长单调递增子序列,由于是否加一个元素与之前解的最后一个元素大小有关,因此用j记录
dp[i-1]的最优解最后一个元素,
dp[i]=dp[i-1]+1 a[i]>a[j],j记录之前的最后一个元素index
dp[i-1] a[i]<a[j]
但是后来才发现这个DP是错的,举个范例, 1 3 2 2.5 解为1 2 2.5,但是实际上述跑出来是1 3 ,因为后面会因为
比之前的3小而放弃,所有DP有时候模糊写了一个算法,好像是对的,往往是错的。。。。。
正确的算法是O(n^2)的,思路仿照最大字段和,dp[i]不是原问题的子空间最优解,而是包含a[i]在内的子空间的
最优解,然后再遍历一遍 dp[1...n]就是原问题最优解了。
这个是从另一个角度来划分子空间,从解的最有一个元素是那个index的角度,可能的只有1...n
dp[i]=max{dp[x], x<i, a[x]<a[i]}+1
为什么不考虑比a[i]大的a[x]呢?因为定义啊,子空间最后一个元素就是a[i], 如果前面大的话只能放弃a[i], 那么得出的解就不符合定义
这个想想其实挺巧妙的。
另外当时想最大字段和为啥是:
b[j]= max{a[j], b[j-1]+a[j]}, 也即如果前面一个是负的,就全部丢弃,选a[j],否则累加a[j]?
我当时可不可能是 (sum=)a[k...j-1]+a[j] 会更优,k>1? 后来发现不可能, 假设b[j-1] <0, a[j] 较大,如果b[j]里面,有
更优解 a[k...j-1,j] 那么大于a[j] 所以sum a[k...j-1]>0, b[j-1]比存在一个大于0的最优解,与假设矛盾,所以b[j-1]<0
时,a[j]必是最优解,没有其他情况大于他。
所以总之,完全不依赖模板题写一个新的DP是比较难的,因为极有可能就是错的,验证就是举反例,但有时不好举,举不出又不能说明正确,当时我问沈老师,
他也说了,DP算法是有一点难的算法