uva 311 - Packets

点击打开链接uva 311


题目意思:

有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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值