POJ 1017 Packets 贪心

贪心策略也就是优先放大的,再用小的填剩余的空子。

我们注意到其实那些用来填空子的小格子其实也就只有1x1和2x2这两种,为什么呢?如果我们放6x6的,没有空位子。如果我们用5x5的,我们只能用1x1的来填。如果我们用4x4的,我们可以用2x2,1x1的来填。如果我们用3x3的我们还是可以用1x1,2x2的来填。

这样一想,其实也就是考虑1x1,2x2的格子了。

很简单的就可以得出一个关系。

填1个6之后,没有空位。

填1个5之后,还有11个空位。

填1个4之后,还有5个2x2的空位。

填1个3之后,还有5个2x2的空位,7个1x1的空位。

填2个3之后,还有3个2x2的空位,6个1x1的空位。

填3个3之后,还有1个2x2的空位,还有5个1x1的空位。

填4个3之后,没有空位。

这样一来就很简单了,我的代码有点复杂,可以优化,但是我感觉代码重要的是复杂度,长度不太重要,所以就这么长了。

#include <map>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define MAX_N 10005

using namespace std;

int main()
{
    //freopen("in.txt", "r", stdin);

    int packets[7];
    while (1)
    {
        bool End = true;
        for (int i = 1; i <= 6; i++)
        {
            scanf("%d", &packets[i]);
            if (packets[i])
                End = false;
        }
        if (End)
            break;

        int ans = packets[6] + packets[5] + packets[4];
        int t1 = packets[5] * 11;
        int t2 = packets[4] * 5;

        ans += (packets[3] + 3) / 4;
        int n = packets[3] % 4;
        if (n == 1)
        {
            t2 += 5;
            t1 += 7;
        }
        else if (n == 2)
        {
            t2 += 3;
            t1 += 6;
        }
        else if (n == 3)
        {
            t2 += 1;
            t1 += 5;
        }

        if (packets[2] >= t2)
            packets[2] -= t2;
        else
        {
            t2 -= packets[2];
            t1 += t2 * 2;
            packets[2] = 0;
        }

        if (packets[1] >= t1)
            packets[1] -= t1;
        else
        {
            t1 -= packets[1];
            packets[1] = 0;
        }

        if (!packets[2] && !packets[1])
            printf("%d\n", ans);
        else
        {
            t1 = 0;
            if (packets[2])
            {
                int temp = (packets[2] + 8) / 9;
                ans += temp;
                t1 = 36 - (packets[2] % 9) * 4;
            }
            if (packets[1] && packets[1] >= t1)
            {
                ans += (packets[1] - t1 + 35) / 36;
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值