poj 1017 Packets 贪心

题目

题目链接:http://poj.org/problem?id=1017

题目来源:《挑战》练习题

简要题意:给定 1×16×6 物品的个数,求最少需要多少个 6×6 的箱子可以放入这些物品。

数据范围:未知

题解

一道题意简单,但是需要仔细讨论的好题。

6×6 直接放入就行了。

5×5 每个都必须占一个箱子,最好的情况就是填上 11 1×1

4×4 每个必须占一个箱子,最好的情况是塞上 2×2 物品, 2×2 可以折换成 1×1 ,因此忽略。

3×3 最好的情况就是 4 个凑出一个,如果有多出来需要分情况讨论,比较复杂。

2×2最好是 9 个凑出一个,空余的可以折合成4 1×1 的。

1×1 的话只能 36 个凑一个。

实现

仔细分情况就行了,比较难分析的是 3×3 的时候的情况。

给的样例非常好,可以察觉到其中的玄机。

代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
int a[15];

void cal5(int &ans) {
    ans += a[5];
    a[1] = max(a[1]-a[5]*11, 0);
}

void cal4(int &ans) {
    ans += a[4];
    a[2] -= a[4]*5;
}

void cal3(int &ans) {
    ans += (a[3]+3)/4;
    int rest = a[3]%4;
    if (rest == 1) {
        a[2] -= 5;
        a[1] -= 7;
    } else if (rest == 2) {
        a[2] -= 3;
        a[1] -= 6;
    } else if (rest == 3) {
        a[2] -= 1;
        a[1] -= 5;
    }
}

void cal2(int &ans) {
    if (a[2] > 0) {
        ans += (a[2]+8)/9;
        int rest = (9-a[2]%9)%9;
        a[1] -= rest*4;
    } else {
        a[1] += a[2]*4;
    }
}

void cal1(int &ans) {
    if (a[1] > 0) {
        ans += (a[1]+35)/36;
    }
}

int main()
{
    while (1) {
        int sum = 0;
        for (int i = 1; i <= 6; i++) {
            scanf("%d", a+i);
            sum += a[i];
        }
        if (!sum) break;
        int ans = a[6];
        cal5(ans);
        cal4(ans);
        cal3(ans);
        cal2(ans);
        cal1(ans);
        printf("%d\n", ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值