题目意思:
有6种箱子1x1 2x2 3x3 4x4 5x5 6x6,现在要把这些箱子装入一个6X6的箱子里,相同的装不下,问最少需要几个6x6这种箱子
解题思路:
1思路:贪心+模拟
2分析:6种箱子 1x1 2x2 3x3 4x4 5x5 6x6,最大的6x6可以装下其它5种箱子,要求6x6的箱子个数最少,那么就有所有的6x6箱子都要满足最大容量的装下所有的东西,就是总的浪费最少。现在来分析对于6种箱子什么时候课以减少箱子的总数
1 6x6有num[6]个,那么ans至少需要num[6]
2 5x5,那么在6x6中装下一个5x5后,只能够装1x1的箱子,那么11个1x1就可以和一个5x5组合一个6x6箱子
3 4x4,那么在6x6中装下一个4x4后,还可以选择装2x2和1x1,但是要达到最小的箱子数,那么必须先把2x2的装完然后在装1x1
4 3x3,四个3x3组合成一个6x6,所以先判断几个3x3,然后还可以装下2x2,和1x1,但是3x3个数不同可以装的2x2和1x1也是不同的
5 2x2,9个2x2可以组合成一个6x6,所以先判断几个2x2,然后只能装下1x1
6 1x1,36和1x1可以组合成一个6x6,所以先判断有几个1x1,然后求出ans
3注意:如果当前num[i]为负数,那么直接令它为0即可。
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define MAXN 1010
long long ans;
long long num[7];
void solve() {
ans = num[6];/*ans至少需要num[6]*/
for (int i = 5; i >= 1; i--) {/*枚举剩余5种箱子,然后按照上面的思路模拟*/
if (!num[i]) continue;/*为0直接跳过*/
if (i == 5) {
ans += num[i];
num[1] -= 11 * num[i];
if (num[1] < 0) num[1] = 0;
}
else if (i == 4) {
ans += num[i];
if (num[2] - num[i]*5 < 0) {/*如果num[2]不够填补在4x4上*/
num[1] -= (num[i]*5 - num[2])*4;
num[2] = 0;
if (num[1] < 0) num[1] = 0;
}
else num[2] -= num[i]*5;
}
else if (i == 3) {
if (num[i] > 4) {
ans += num[i] / 4;
num[i] %= 4;
}
if (num[i] > 0) {
ans++;
if (num[i] < 4) {
num[2] -= (7 - num[i]*2);
num[1] -= (8 - num[i]);
if (num[1] < 0) num[1] = 0;
if (num[2] < 0) num[2] = 0;
}
}
}
else if (i == 2) {
if (num[i] > 9) {
ans += num[i] / 9;
num[i] %= 9;
}
if (num[i] > 0) {
ans++;
num[1] -= 36 - num[i]*4;
if (num[1] < 0) num[1] = 0;
}
}
else {
if (num[i] > 36) {
ans += num[i] / 36;
num[i] %= 36;
}
if (num[i] > 0) ans++;
}
}
printf("%lld\n", ans);
}
int main() {
//freopen("input.txt", "r", stdin);
int sum, i;
while (1) {
sum = 0;
for (i = 1; i < 7; i++) {
scanf("%lld", &num[i]);
sum += num[i];
}
if (!sum) break;/*如果6个数全部为0,那么直接退出*/
solve();
}
return 0;
}