3219. 切蛋糕的最小总开销 II

题目有一个 m x n 大小的矩形蛋糕,需要切成 1 x 1 的小块。

给你整数 m ,n 和两个数组:

  • horizontalCut 的大小为 m - 1 ,其中 horizontalCut[i] 表示沿着水平线 i 切蛋糕的开销。
  • verticalCut 的大小为 n - 1 ,其中 verticalCut[j] 表示沿着垂直线 j 切蛋糕的开销。

一次操作中,你可以选择任意不是 1 x 1 大小的矩形蛋糕并执行以下操作之一:

  1. 沿着水平线 i 切开蛋糕,开销为 horizontalCut[i] 。
  2. 沿着垂直线 j 切开蛋糕,开销为 verticalCut[j] 。

每次操作后,这块蛋糕都被切成两个独立的小蛋糕。

每次操作的开销都为最开始对应切割线的开销,并且不会改变。

请你返回将蛋糕全部切成 1 x 1 的蛋糕块的 最小 总开销。

人话:参考0X3F题解,问题可以被理解成,最小生成树的 Kruskal 算法 的使用,也就是:

先将边从小到大排列,从小到大的添加不构成「环路」的边

然后需要注意的是,如果当下要把竖向 的切面连起来,就要看这时候横向的有多少组,有几组就要连几次,最开始的组数当然就是 m-1 和 n-1了。代码里使用 i j 来表示已经粘了的次数。

小知识 :&& 的优先级比 || 要高

易错:纵向连完了, 或者 横向存在更小的边时,做一次横向连接,因此是两个进入条件:

如果把两种条件写在一起,就会出现先后顺序的问题,写错了往往会造成越界,具体如下:

//  正确写法
if( j == n - 1 || i < m - 1 && horizontalCut[i] < verticalCut[j]){}

//  越界写法
if( i < m - 1 && horizontalCut[i] < verticalCut[j] || j == n - 1){}

把边界判定条件提前,是更明智的选择。

class Solution {
public:
    long long minimumCost(int m, int n, vector<int>& horizontalCut, vector<int>& verticalCut) {
        int i = 0, j = 0;                                           //  i j  表示当前要去合并的切线

        long long ret = 0;
        std::sort(horizontalCut.begin(), horizontalCut.end());      //  最小生成树排序
        std::sort(verticalCut.begin(), verticalCut.end());

        while(i < m - 1 || j < n - 1){
            //  j == n - 1放前面,否则会越界报错
            if( i < m - 1 && horizontalCut[i] < verticalCut[j] || j == n - 1){
                ret += (n - j) * horizontalCut[i];
                i++;
            }else{
                ret += (m - i) * verticalCut[j];
                j++;
            }
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值