数据很小,适合区间dp的入门
对于第[i, j]堆,无论你怎么合并,无论你先选哪两堆结合,当你把[i, j]合成一堆的那一步的时候,花费肯定就是sum[i....j]
可以用纸模拟下。
那么我们设dp[i][j]表示把i...j堆合成一堆的时候的最小花费。
比如dp[1][1] = 0。dp[1][2] = a[1] + a[2];
那么要求dp[i][j],则可以是dp[i][k] + dp[k + 1][j] + cost
注意dp的时候的顺序,因为要求dp[1][n],则需要用到dp[1][k]和dp[k][n]
你需要考虑下怎么for,才能使得子问题已经被算出,建议一开始用dfs + 记忆化做。
这里dp的顺序应该是先算出2个集合的,3个、4个、......
就是先算出dp[1][2], dp[2][3],这使得求dp[1][3]成为可能。
all dp[i][i] = 0
#include #include #include #include #include #include #define IOS ios::sync_with_stdio(false)using namespace std;#define inf (0x3f3f3f3f)typedef long long int LL;#include #include #include #include #include
View Code
平行四边形优化,其实我还不是很懂。那个证明太难了。
#include #include #include #include #include #include #define IOS ios::sync_with_stdio(false)using namespace std;#define inf (0x3f3f3f3f)typedef long long int LL;#include #include #include #include #include
View Code 简单来说,就是设s[i][j]表示第i---j堆石子合并的时候,在第s[i][j]那里合并,是最优的。
那么可以证明的是:s[i][j - 1] <= s[i][j] <= s[i + 1][j]
那么只需要枚举里面的值就好了。