来源: LeetCode 1039 多变三角剖分的最低得分
题目描述
给定 N,想象一个凸 N 边多边形,其顶点按顺时针顺序依次标记为 A[0], A[i], ..., A[N-1]。
假设您将多边形剖分为 N-2 个三角形。对于每个三角形,该三角形的值是顶点标记的乘积,三角剖分的分数是进行三角剖分后所有 N-2 个三角形的值之和。
返回多边形进行三角剖分后可以得到的最低分。
示例 1:
输入:[1,2,3]
输出:6
解释:多边形已经三角化,唯一三角形的分数为 6。
示例 2:
输入:[3,7,4,5]
输出:144
解释:有两种三角剖分,可能得分分别为:3*7*5 + 4*5*7 = 245,或 3*4*5 + 3*4*7 = 144。最低分数为 144。
示例 3:
输入:[1,3,1,4,1,5]
输出:13
解释:最低分数三角剖分的得分情况为 1*1*3 + 1*1*4 + 1*1*5 + 1*1*1 = 13。
提示:
3 <= A.length <= 50
1 <= A[i] <= 100
思路分析
这道题仍然是一道典型的区间DP
区间DP最关键的就是要确定基本情况和如何刻画区间
假设我们得到的多边形是三角形那么答案就是这三个点的乘积
一个多边形我们可以用点集来表示
dp[i][j] 表示[i,j]区间的最低得分
那么区分子问题与父问题的参数应该就是区间长度
base case 为 长度为3 那么低于3的长度都应该为0
- 输入
dp[i][j] = 0 j - i <2
- 输出
dp[0][len - 1]
- 状态转换
dp[i][j] = dp[i][k] + dp[k][j] + A[i]*A[k]*A[j]
k from i + 1 to j-1
- 区间长度作为区分子问题和父问题的点
代码
class Solution {
public:
int minScoreTriangulation(vector<int>& A) {
vector<vector<int>> dp(A.size(), vector<int>(A.size(), 0));
for(int r = 2; r<A.size(); ++r){
int j;
for(int i = 0; i+r<A.size(); ++i){
j = i+r;
dp[i][j] = INT_MAX;
for(int k = i+1; k<j; ++k){
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + A[i] * A[k] * A[j]);
}
}
}
return dp[0].back();
}
};
算法分析
时间复杂度: O(N^3)
空间复杂度: O(N^2)
代码改进
这道题理论上可以用贪心算法去做
动态规划每一层去求解dp[i][j]的时候都要求分割点,即i,j,k将多边形分为了三部分,然后我们针对i,j,k建立了一个三重循环
我们可以假设每一次只用一条线将多边形分为两部分,那么分割的这个线段上的点就要计算两次
我们期望每次分割带来的代价最小,那就选择乘积最小的一对
通过N^2时间求解每一对的最小乘积
每一次选择后会将原区间分为两部分,再依次选择在这两部分内的最小乘积,可以在O(N^2)时间内解决该问题
理论上应该是正确的,很遗憾我没时间实现
相似扩展
归纳总结
典型区间DP