#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param monsterLength int整型 线段长度
* @param monsterPoint int整型vector 切割点位置
* @return int整型
*/
int attackMonster(int monsterLength, vector<int>& monsterPoint) {
int numOfPoints = monsterPoint.size() + 2;
vector<int> points(numOfPoints);
points[0]=0;
points[numOfPoints-1]=monsterLength;
for (int i=1; i<numOfPoints-1; i++) {
points[i]=monsterPoint[i-1];
}
sort(points.begin(),points.end());
for (int i:points) {
cout<<i<<"|";
}
// monsterPoint加上头尾两个点
// dp[i][j]表示从第i个点到第j个点,这中间的最小切割成本
// 相邻点之间切割成本为0,所以dp[i][i+1]=0
// -1表示该值尚未被初始化
vector<vector<int>> dp(numOfPoints, vector<int>(numOfPoints, -1));
for (int i = 0; i < numOfPoints-1; i++) {
// 一跳邻居的间距为0
dp[i][i + 1] = 0;
}
for (int j = 2; j < numOfPoints; j++) {// 从2跳邻居开始一直到numOfPoints跳邻居
for (int i = 0; i+j < numOfPoints; i++) {
// 计算j跳邻居间距dp[i][i+j]
int minPart=dp[i][i+1]+dp[i+1][i+j];
for (int k=2; k<j; k++) {
int tempPart=dp[i][i+k]+dp[i+k][i+j];
if (tempPart<minPart) {
minPart=tempPart;
}
}
dp[i][i+j]=minPart+points[i+j]-points[i];
}
}
for (int i=0; i<numOfPoints; i++) {
for (int j=0; j<numOfPoints; j++) {
cout<<dp[i][j]<<",";
}
cout<<"|";
}
return dp[0][numOfPoints-1];
}
};
动态规划,monsterPoint加上头尾两个点,对于这N+2个点,开始搜索
dp[i][i+j]表示从第i个点到第i+j个点,这中间的最小切割成本(开区间)
初始化:相邻点之间切割成本为0,所以dp[i][i+1]=0
对j从2开始遍历,j表示“邻居跳数”,从2跳邻居开始算总成本
保证计算 j 跳邻居时,跳数比j小的成本已经全部计算过了
然后对位置i进行遍历
从 i 跳到 i+j 要跳两次,第一次跳到切割点,因此 k 对切割点进行遍历
三次遍历实现最后的算法,复杂度n^3



京公网安备 11010502036488号