题目意思:
有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; }