LeetCode 1000. Minimum Cost to Merge Stones
Posted Yannick Carrasco
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1000. Minimum Cost to Merge Stones相关的知识,希望对你有一定的参考价值。
题目链接:https://leetcode.com/problems/minimum-cost-to-merge-stones/
题意:有$N$堆石头排成一行,第$i$堆石头有$stones[i]$个石头,现在需要将所有堆的石头合并成一堆,以堆为单位进行操作,每次只能将$K$个连续的堆合并成一堆,每次合并的代价为这$K$堆石头的石头数之和,问合成一堆的最小代价是多少,若不能合并成一堆,则返回-1。石头的堆数不超过30,$K$的值不超过30,每堆石头的数目不超过100。
思路:首先确定能合成一堆的条件,即$N=K,2*K-1,3*K-2...$,因此$N$满足的条件为$(N-1)%K=0$,区间dp的思路,$dp[i][j]表示从$i$堆石头到第$j$堆石头需要的代价。枚举$k$,dp方程为$dp[i][j]=dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j])$,当$(j-i)%K==0$时,即恰好可以合并成一堆时,需要加一次代价值,即$dp[i][j]+=sum[j]-sum[i-1]$,枚举k时,由于石子堆数-1必须为$K-1$的倍数,因此k可每隔K-1个枚举一次。
class Solution { public: int mergeStones(vector<int>& stones, int K) { int cnt=stones.size(); while(cnt>=K) //能否合并成一堆 cnt = cnt/K+cnt%K; if(cnt!=1) return -1; int **dp = new int *[stones.size()]; for(int i=0;i<stones.size();i++){ dp[i]= new int [stones.size()]; for(int j=0;j<stones.size();j++) dp[i][j]=0; //初始代价和为0 } int *sum = new int[stones.size()+1]; memset(sum,0,(stones.size()+1)*4 ) ; sum[0]=stones[0]; for(int i=1;i<stones.size();i++) sum[i]=sum[i-1]+stones[i]; //前缀和 for(int i=stones.size()-1;i>=0;i--) for(int j=i;j<stones.size();j++){ dp[i][j]=1e9; int cnt; if(i==0) cnt = sum[j]; else cnt = sum[j]-sum[i-1]; if(j-i<K-1){ //石子堆数不够合并成一堆 dp[i][j]=0; continue; } for(int k=i;k<j;k+=(K-1) ){ //枚举k dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]); } if((j-i)%(K-1)==0){ dp[i][j]+=cnt; } } return dp[0][stones.size()-1]; } };
以上是关于LeetCode 1000. Minimum Cost to Merge Stones的主要内容,如果未能解决你的问题,请参考以下文章
[LeetCode] 1249. Minimum Remove to Make Valid Parentheses
[LeetCode] 1249. Minimum Remove to Make Valid Parentheses
Leetcode-5047 Minimum Score Triangulation of Polygon(多边形三角剖分的最低得分)