【贪心数学困难题】1739. 放置盒子
创始人
2024-05-21 22:17:20

⭐️前面的话⭐️

本篇文章介绍【贪心数学困难题】1739. 放置盒子题解,展示语言java。

📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2023年1月31日🌴
✉️坚持和努力一定能换来诗与远方!
💭推荐书籍:📚《算法》,📚《算法导论》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!


📌导航小助手📌

  • ⭐️1739. 放置盒子⭐️
    • 🔐题目详情
    • 💡解题思路
    • 🔑源代码
  • 🌱总结


⭐️1739. 放置盒子⭐️

1739. 放置盒子

🔐题目详情

难度困难

有一个立方体房间,其长度、宽度和高度都等于 n 个单位。请你在房间里放置 n 个盒子,每个盒子都是一个单位边长的立方体。放置规则如下:

  • 你可以把盒子放在地板上的任何地方。
  • 如果盒子 x 需要放置在盒子 y 的顶部,那么盒子 y 竖直的四个侧面都 必须 与另一个盒子或墙相邻。

给你一个整数 n ,返回接触地面的盒子的 最少 可能数量*。*

示例 1:

img

输入:n = 3
输出:3
解释:上图是 3 个盒子的摆放位置。
这些盒子放在房间的一角,对应左侧位置。

示例 2:

img

输入:n = 4
输出:3
解释:上图是 3 个盒子的摆放位置。
这些盒子放在房间的一角,对应左侧位置。

示例 3:

img

输入:n = 10
输出:6
解释:上图是 10 个盒子的摆放位置。
这些盒子放在房间的一角,对应后方位置。

提示:

  • 1 <= n <= 109

💡解题思路

解题思路: 贪心思想+数学推理题

想要占地板数最少,那么需要靠墙角进行方块的放置,因为墙角天然提供了两个侧面的消耗,这是这道题贪心的一个点吧,并且以类阶梯放置时,所占地面的方块数最少,下面我们来进行找规律。

地面上盒子数为111时,最多可以放111个盒子。
1

地面上盒子数为222时,最多可以放222个盒子。

2
地面上盒子数为333时,最多可以放444个盒子,不妨将这种放置情况称为完整的阶梯堆,以下简称阶梯堆。

3
地面上盒子数为444时,最多可以放555个盒子,相比于上一个阶梯堆,多了111个地面盒子,多了111个盒子上限。
4

地面上盒子数为555时,最多可以放777个盒子,相比于上一个阶梯堆,多了222个地面盒子,多了1+21+21+2个盒子上限。
5
地面上盒子数为666时,最多可以放101010个盒子,相比于上一个阶梯堆,多了333个地面盒子,多了1+2+31+2+31+2+3个盒子上限,形成了一个完整放置的阶梯堆。
6
地面上盒子数为777时,最多可以放111111个盒子,相比于上一个阶梯堆,多了111个地面盒子,多了111个盒子上限。
7

地面上盒子数为888时,最多可以放131313个盒子,相比于上一个阶梯堆,多了222个地面盒子,多了1+21+21+2个盒子上限。
8

地面上盒子数为999时,最多可以放161616个盒子,相比于上一个阶梯堆,多了333个地面盒子,多了1+2+31+2+31+2+3个盒子上限。
9
地面上盒子数为101010时,最多可以放161616个盒子,相比于上一个阶梯堆,多了444个地面盒子,多了1+2+3+41+2+3+41+2+3+4个盒子上限,并且形成了一个新的阶梯堆。
10

通过这些举例,我们可以看出一些规律,当地面放置的盒子数为111,1+21+21+2,1+2+31+2+31+2+3,…,1+2+3+...+i1+2+3+...+i1+2+3+...+i时,最多放置的盒子堆是一个阶梯堆。

地面盒子为1+2+3+...+i1+2+3+...+i1+2+3+...+i时,即i×(1+i)2\frac{i\times(1+i)}{2}2i×(1+i)​(等差数列求和),所对应盒子的上限为maxNmaxNmaxN(裂项相消):

1+(1+2)+(1+2+3)+...+(1+2+3+...+i)=∑i=1ii×(1+i)21+(1+2)+(1+2+3)+...+(1+2+3+...+i)=\sum_{i=1}^{i}{\frac{i\times(1+i)}{2}} 1+(1+2)+(1+2+3)+...+(1+2+3+...+i)=i=1∑i​2i×(1+i)​

因为从顶端往下数,每层的盒子数为111,1+21+21+2,1+2+31+2+31+2+3,…,1+2+3+...+i1+2+3+...+i1+2+3+...+i。

利用裂项相消计算得:

∑i=1ii×(1+i)2=∑i=1i(i×(1+i)2×[(i+2)−(i−1)]3)=∑i=1i(i(i+1)(i+2)6−(i−1)i(i+1)6)=16∑i=1i[i(i+1)(i+2)−(i−1)i(i+1)]=[(1×2×3)−(0×1×2)+(2×3×4)−(1×2×3)+...+i(i+1)(i+2)−(i−1)i(i+1)]=16[i(i+1)(i+2)−(0×1×2)]=i(i+1)(i+2)6\begin{aligned} \sum_{i=1}^{i}{\frac{i\times(1+i)}{2}}&=\sum_{i=1}^{i}({\frac{i\times(1+i)}{2}}\times\frac{[(i+2)-(i-1)]}{3})\\ &=\sum_{i=1}^{i}(\frac{i(i+1)(i+2)}{6}-\frac{(i-1)i(i+1)}{6})\\ &=\frac{1}{6}\sum_{i=1}^{i}[i(i+1)(i+2)-(i-1)i(i+1)]\\ &=[(1\times2\times3)-(0\times1\times2)+(2\times3\times4)-(1\times2\times3)+...+i(i+1)(i+2)-(i-1)i(i+1)]\\ &=\frac{1}{6}[i(i+1)(i+2)-(0\times1\times2)]\\ &=\frac{i(i+1)(i+2)}{6}\\ \end{aligned} i=1∑i​2i×(1+i)​​=i=1∑i​(2i×(1+i)​×3[(i+2)−(i−1)]​)=i=1∑i​(6i(i+1)(i+2)​−6(i−1)i(i+1)​)=61​i=1∑i​[i(i+1)(i+2)−(i−1)i(i+1)]=[(1×2×3)−(0×1×2)+(2×3×4)−(1×2×3)+...+i(i+1)(i+2)−(i−1)i(i+1)]=61​[i(i+1)(i+2)−(0×1×2)]=6i(i+1)(i+2)​​

最终maxN=i(i+1)(i+2)6maxN=\frac{i(i+1)(i+2)}{6}maxN=6i(i+1)(i+2)​。

根据变化规律,在阶梯堆基础上添加地面盒子数jjj个,盒子上限会增加1+2+3+...+j=j×(1+j)21+2+3+...+j=\frac{j\times(1+j)}{2}1+2+3+...+j=2j×(1+j)​。【不妨称作添加规律】

对于本题我们可以算出最大阶梯堆的地面盒子数量不妨设为x=1+2+...+k=k×(1+k)2x=1+2+...+k=\frac{k\times(1+k)}{2}x=1+2+...+k=2k×(1+k)​,然后再将剩余的盒子以以上【添加规律】模拟计数得出yyy,即可的最终所占的地面盒子数ans=x+yans=x+yans=x+y。

🔑源代码

Java代码1:

class Solution {public int minimumBoxes(int n) {int maxN = 0;int ans = 0;int k = 1;while (k * (1 + k) / 2 + maxN <= n) {maxN += k * (1 + k) / 2;k++;}//k多记了1k--;//xans = k * (1 + k) / 2;k = 1;//基于阶梯堆,每增加一块地面盒子,上限增加k(k从1递增)while (maxN < n) {maxN += k;ans++;k++;}return ans;}
}

Java代码2:

class Solution {public int minimumBoxes(int n) {int maxN = 1;int ans = 0;int k = 1;while (maxN <= n) {k++;maxN = (int) ((long) k * (1 + k) * (2 + k) / 6);}//k多记了1k--;maxN = (int) ((long) k * (1 + k) * (2 + k) / 6);//xans = k * (1 + k) / 2;k = 1;//基于阶梯堆,每增加一块地面盒子,上限增加k(k从1递增)while (maxN < n) {maxN += k;ans++;k++;}return ans;}
}

C++代码1:

class Solution {
public:int minimumBoxes(int n) {int ans = 0;int k = 1;int maxN = 0;while (maxN + k * (1 + k) / 2 <= n) {maxN += k * (1 + k) / 2;k++;}//k多加1--k;ans = k * (1 + k) / 2;k = 1;while (maxN < n){ans++;maxN += k;k++;}return ans;}
};

C++代码2:

class Solution {
public:int minimumBoxes(int n) {int ans = 0;int k = 1;int maxN = 1;while (maxN <= n) {k++;maxN = (int) ((long) k * (k + 1) * (k + 2) / 6);}//k多加1--k;maxN = (int) ((long) k * (k + 1) * (k + 2) / 6);ans = k * (1 + k) / 2;k = 1;while (maxN < n){ans++;maxN += k;k++;}return ans;}
};

C语言代码1:

int minimumBoxes(int n){int ans = 0;int k = 1;int maxN = 0;while (maxN + k * (1 + k) / 2 <= n) {maxN += k * (1 + k) / 2;k++;}//k多加1--k;ans = k * (1 + k) / 2;k = 1;while (maxN < n) {ans++;maxN += k;k++;}return ans;
}

C语言代码2:

int minimumBoxes(int n){int ans = 0;int k = 1;int maxN = 1;while (maxN <= n) {k++;maxN = (int) ((long) k * (k + 1) * (k + 2) / 6);}//k多加1--k;maxN = (int) ((long) k * (k + 1) * (k + 2) / 6);ans = k * (1 + k) / 2;k = 1;while (maxN < n) {ans++;maxN += k;k++;}return ans;
}

🌱总结

本题主要有两个难点,一个是贪心思维,知道从墙角下手,第二个就是数学规律推理,找出盒子变化规律。

优化参考:
1

class Solution {public int minimumBoxes(int n) {int x = (int) Math.cbrt(6L * n);int ans = x * (x + 1) / 2;int maxN = (int) ((long) x * (x + 1) * (x + 2) / 6);if (maxN > n) {maxN -= ans;ans -= x;}return ans + (int) Math.ceil((-1 + Math.sqrt(1 + 8 * (n - maxN))) / 2);}
}
class Solution {
public:int minimumBoxes(int n) {int x = cbrt(6L * n);int ans = x * (x + 1) / 2;int max_n = (long) x * (x + 1) * (x + 2) / 6;if (max_n > n) {max_n -= ans;ans -= x;}return ans + ceil((-1 + sqrt(1 + 8 * (n - max_n))) / 2);}
};

参考资料:
https://leetcode.cn/problems/building-boxes/solution/mei-xiang-ming-bai-yi-ge-dong-hua-miao-d-8vbe/

觉得文章写得不错的老铁们,点赞评论关注走一波!谢谢啦!

1-99

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...