• 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];
        }
    };
    

      

  • 相关阅读:
    转载:PHP JSON_ENCODE 不编码中文汉字的方法
    【TP3.2】:日志记录和查看
    PHP原生:分享一个轻量级的缓存类=>cache.php
    python: 基本的日期与时间转换
    python: 随机选择
    计算机bit是什么意思
    Python: 矩阵与线性代数运算
    Python numpy 安装以及处理报错 is not a supported wheel on this platform
    Python: 大型数组运算
    Python numpy有什么用?
  • 原文地址:https://www.cnblogs.com/dlutjwh/p/11371005.html
Copyright © 2020-2023  润新知