LeetCode 1547. 切棍子的最小成本

题目链接:LeetCode 1547. 切棍子的最小成本

题意:

   有一根长度为 n 个单位的木棍,棍上从 0 到 n 标记了若干位置。例如,长度为 6 的棍子可以标记如下:

给你一个整数数组 cuts ,其中 cuts[i] 表示你需要将棍子切开的位置。

你可以按顺序完成切割,也可以根据需要更改切割的顺序。

每次切割的成本都是当前要切割的棍子的长度,切棍子的总成本是历次切割成本的总和。对棍子进行切割将会把一根木棍分成两根较小的木棍(这两根木棍的长度和就是切割前木棍的长度)。请参阅第一个示例以获得更直观的解释。

返回切棍子的 最小总成本 。

 

解题思路:

    区间DP,根据代码理解

class Solution {

    /**
     * @param Integer $n
     * @param Integer[] $cuts
     * @return Integer
     */
    function minCost($n, $cuts) {
    	$dp = array();         // 二维数组   dp[i][j] 表示将第i段到第j段完全切开的最小代价
    	array_push($cuts, 0);  // 将0和n插入数组中
    	array_push($cuts, $n);
        sort($cuts);  // 排序
    	$m = count($cuts)-1;
    	for($i = 1; $i <= $m; $i++) {
    		for($j = 1; $j <= $m; $j++) {
    			$dp[$i][$j] = -1; // 初始化
    		}
    	}
    	for($i = 1; $i <= $m; $i++) {
    		$dp[$i][$i] = 0;  // 自身到自身为0
    	}
    	for($len = 1; $len < $n; $len++) {       // 当前区间长度,从1开始是因为0已经设置过了
    		for($left = 1; $left <= $m; $left++) {  // 从所有情况开始
    			$right = $left + $len;
    			if($right > $m) {
    				break;
    			}
    			for($mid = $left; $mid < $right; $mid++) {
    				 if($dp[$left][$mid] == -1 || $dp[$mid+1][$right] == -1) {
    				 	continue;
    				 }
    				$v = $dp[$left][$mid] + $dp[$mid+1][$right] + $cuts[$right] - $cuts[$left-1];
 // cuts[right]-cuts[left-1] 为当前木根的长度
 // $dp[$left][$mid] + $dp[$mid+1][$right]  接下来切左段和右段的长度
    				if($dp[$left][$right] == -1 || $dp[$left][$right] > $v) {
    					$dp[$left][$right] = $v;
    				}
    			}
    		}
    	}
    	return $dp[1][$m];
    }
}

你可能感兴趣的:(LeetCode,动态规划)