贪心策略也就是优先放大的,再用小的填剩余的空子。
我们注意到其实那些用来填空子的小格子其实也就只有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;
}