⭐️前面的话⭐️
本篇文章介绍【贪心数学困难题】1739. 放置盒子题解,展示语言java。
📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2023年1月31日🌴
✉️坚持和努力一定能换来诗与远方!
💭推荐书籍:📚《算法》,📚《算法导论》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
📌导航小助手📌
- ⭐️1739. 放置盒子⭐️
- 🔐题目详情
- 💡解题思路
- 🔑源代码
- 🌱总结
⭐️1739. 放置盒子⭐️
1739. 放置盒子
🔐题目详情
难度困难
有一个立方体房间,其长度、宽度和高度都等于 n
个单位。请你在房间里放置 n
个盒子,每个盒子都是一个单位边长的立方体。放置规则如下:
- 你可以把盒子放在地板上的任何地方。
- 如果盒子
x
需要放置在盒子y
的顶部,那么盒子y
竖直的四个侧面都 必须 与另一个盒子或墙相邻。
给你一个整数 n
,返回接触地面的盒子的 最少 可能数量*。*
示例 1:
输入:n = 3
输出:3
解释:上图是 3 个盒子的摆放位置。
这些盒子放在房间的一角,对应左侧位置。
示例 2:
输入:n = 4
输出:3
解释:上图是 3 个盒子的摆放位置。
这些盒子放在房间的一角,对应左侧位置。
示例 3:
输入:n = 10
输出:6
解释:上图是 10 个盒子的摆放位置。
这些盒子放在房间的一角,对应后方位置。
提示:
1 <= n <= 109
💡解题思路
解题思路: 贪心思想+数学推理题
想要占地板数最少,那么需要靠墙角进行方块的放置,因为墙角天然提供了两个侧面的消耗,这是这道题贪心的一个点吧,并且以类阶梯放置时,所占地面的方块数最少,下面我们来进行找规律。
地面上盒子数为
1
1
1时,最多可以放
1
1
1个盒子。
地面上盒子数为 2 2 2时,最多可以放 2 2 2个盒子。
地面上盒子数为
3
3
3时,最多可以放
4
4
4个盒子,不妨将这种放置情况称为完整的阶梯堆,以下简称阶梯堆。
地面上盒子数为
4
4
4时,最多可以放
5
5
5个盒子,相比于上一个阶梯堆,多了
1
1
1个地面盒子,多了
1
1
1个盒子上限。
地面上盒子数为
5
5
5时,最多可以放
7
7
7个盒子,相比于上一个阶梯堆,多了
2
2
2个地面盒子,多了
1
+
2
1+2
1+2个盒子上限。
地面上盒子数为
6
6
6时,最多可以放
10
10
10个盒子,相比于上一个阶梯堆,多了
3
3
3个地面盒子,多了
1
+
2
+
3
1+2+3
1+2+3个盒子上限,形成了一个完整放置的阶梯堆。
地面上盒子数为
7
7
7时,最多可以放
11
11
11个盒子,相比于上一个阶梯堆,多了
1
1
1个地面盒子,多了
1
1
1个盒子上限。
地面上盒子数为
8
8
8时,最多可以放
13
13
13个盒子,相比于上一个阶梯堆,多了
2
2
2个地面盒子,多了
1
+
2
1+2
1+2个盒子上限。
地面上盒子数为
9
9
9时,最多可以放
16
16
16个盒子,相比于上一个阶梯堆,多了
3
3
3个地面盒子,多了
1
+
2
+
3
1+2+3
1+2+3个盒子上限。
地面上盒子数为
10
10
10时,最多可以放
16
16
16个盒子,相比于上一个阶梯堆,多了
4
4
4个地面盒子,多了
1
+
2
+
3
+
4
1+2+3+4
1+2+3+4个盒子上限,并且形成了一个新的阶梯堆。
通过这些举例,我们可以看出一些规律,当地面放置的盒子数为 1 1 1, 1 + 2 1+2 1+2, 1 + 2 + 3 1+2+3 1+2+3,…, 1 + 2 + 3 + . . . + i 1+2+3+...+i 1+2+3+...+i时,最多放置的盒子堆是一个阶梯堆。
地面盒子为 1 + 2 + 3 + . . . + i 1+2+3+...+i 1+2+3+...+i时,即 i × ( 1 + i ) 2 \frac{i\times(1+i)}{2} 2i×(1+i)(等差数列求和),所对应盒子的上限为 m a x N maxN maxN(裂项相消):
1 + ( 1 + 2 ) + ( 1 + 2 + 3 ) + . . . + ( 1 + 2 + 3 + . . . + i ) = ∑ i = 1 i i × ( 1 + i ) 2 1+(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∑i2i×(1+i)
因为从顶端往下数,每层的盒子数为 1 1 1, 1 + 2 1+2 1+2, 1 + 2 + 3 1+2+3 1+2+3,…, 1 + 2 + 3 + . . . + i 1+2+3+...+i 1+2+3+...+i。
利用裂项相消计算得:
∑ i = 1 i i × ( 1 + i ) 2 = ∑ i = 1 i ( i × ( 1 + i ) 2 × [ ( i + 2 ) − ( i − 1 ) ] 3 ) = ∑ i = 1 i ( i ( i + 1 ) ( i + 2 ) 6 − ( i − 1 ) i ( i + 1 ) 6 ) = 1 6 ∑ 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 ) ] = 1 6 [ 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∑i2i×(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))=61i=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)
最终 m a x N = i ( i + 1 ) ( i + 2 ) 6 maxN=\frac{i(i+1)(i+2)}{6} maxN=6i(i+1)(i+2)。
根据变化规律,在阶梯堆基础上添加地面盒子数 j j j个,盒子上限会增加 1 + 2 + 3 + . . . + j = j × ( 1 + j ) 2 1+2+3+...+j=\frac{j\times(1+j)}{2} 1+2+3+...+j=2j×(1+j)。【不妨称作添加规律】
对于本题我们可以算出最大阶梯堆的地面盒子数量不妨设为 x = 1 + 2 + . . . + k = k × ( 1 + k ) 2 x=1+2+...+k=\frac{k\times(1+k)}{2} x=1+2+...+k=2k×(1+k),然后再将剩余的盒子以以上【添加规律】模拟计数得出 y y y,即可的最终所占的地面盒子数 a n s = x + y ans=x+y ans=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多记了1
k--;
//x
ans = 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多记了1
k--;
maxN = (int) ((long) k * (1 + k) * (2 + k) / 6);
//x
ans = 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;
}
🌱总结
本题主要有两个难点,一个是贪心思维,知道从墙角下手,第二个就是数学规律推理,找出盒子变化规律。
优化参考:
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/