解题思路
这是一个装箱问题:
- 需要将不同尺寸的正方形产品装入 的包裹中
- 每种产品的尺寸从 到 不等
- 目标是使用最少的包裹数量
关键思路:
- 的产品一个包裹只能放一个
- 的产品一个包裹只能放一个,剩余空间可以放 的产品
- 的产品一个包裹可以放一个,剩余空间可以放 和 的产品
- 的产品一个包裹可以放四个
- 的产品一个包裹可以放九个
- 的产品一个包裹可以放 个
代码
#include <iostream>
using namespace std;
void solve(int a[6]) {
int ans = 0;
// 处理6*6的箱子
ans += a[5];
// 处理5*5的箱子
ans += a[4];
a[0] = max(0, a[0] - 11 * a[4]); // 每个5*5箱子可以放11个1*1
// 处理4*4的箱子
ans += a[3];
int space4 = 5 * a[3]; // 4*4后的剩余空间可以放2*2和1*1
int use2 = min(a[1], space4); // 先放2*2
a[1] -= use2;
a[0] = max(0, a[0] - (space4 - use2) * 4); // 剩余放1*1
// 处理3*3的箱子
ans += (a[2] + 3) / 4; // 每4个3*3一个箱子
int rem3 = (4 - a[2] % 4) % 4; // 3*3剩余空间
if(rem3 > 0) {
int space3 = rem3 * 9; // 剩余空间
int use2_3 = min(a[1], space3 / 4); // 放2*2
a[1] -= use2_3;
a[0] = max(0, a[0] - (space3 - use2_3 * 4)); // 剩余放1*1
}
// 处理2*2的箱子
ans += (a[1] + 8) / 9; // 每9个2*2一个箱子
int rem2 = (9 - a[1] % 9) % 9; // 2*2剩余空间
if(rem2 > 0) {
a[0] = max(0, a[0] - rem2 * 4); // 剩余放1*1
}
// 处理1*1的箱子
ans += (a[0] + 35) / 36; // 每36个1*1一个箱子
cout << ans << endl;
}
int main() {
int a[6];
while(true) {
bool allZero = true;
for(int i = 0; i < 6; i++) {
cin >> a[i];
if(a[i] != 0) allZero = false;
}
if(allZero) break;
solve(a);
}
return 0;
}
import java.util.Scanner;
public class Main {
public static void solve(int[] a) {
int ans = 0;
// 处理6*6的箱子
ans += a[5];
// 处理5*5的箱子
ans += a[4];
a[0] = Math.max(0, a[0] - 11 * a[4]); // 每个5*5箱子可以放11个1*1
// 处理4*4的箱子
ans += a[3];
int space4 = 5 * a[3]; // 4*4后的剩余空间可以放2*2和1*1
int use2 = Math.min(a[1], space4); // 先放2*2
a[1] -= use2;
a[0] = Math.max(0, a[0] - (space4 - use2) * 4); // 剩余放1*1
// 处理3*3的箱子
ans += (a[2] + 3) / 4; // 每4个3*3一个箱子
int rem3 = (4 - a[2] % 4) % 4; // 3*3剩余空间
if(rem3 > 0) {
int space3 = rem3 * 9; // 剩余空间
int use2_3 = Math.min(a[1], space3 / 4); // 放2*2
a[1] -= use2_3;
a[0] = Math.max(0, a[0] - (space3 - use2_3 * 4)); // 剩余放1*1
}
// 处理2*2的箱子
ans += (a[1] + 8) / 9; // 每9个2*2一个箱子
int rem2 = (9 - a[1] % 9) % 9; // 2*2剩余空间
if(rem2 > 0) {
a[0] = Math.max(0, a[0] - rem2 * 4); // 剩余放1*1
}
// 处理1*1的箱子
ans += (a[0] + 35) / 36; // 每36个1*1一个箱子
System.out.println(ans);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(true) {
int[] a = new int[6];
boolean allZero = true;
for(int i = 0; i < 6; i++) {
a[i] = sc.nextInt();
if(a[i] != 0) allZero = false;
}
if(allZero) break;
solve(a);
}
}
}
def solve(a):
ans = 0
# 处理6*6的箱子
ans += a[5]
# 处理5*5的箱子
ans += a[4]
a[0] = max(0, a[0] - 11 * a[4]) # 每个5*5箱子可以放11个1*1
# 处理4*4的箱子
ans += a[3]
space4 = 5 * a[3] # 4*4后的剩余空间可以放2*2和1*1
use2 = min(a[1], space4) # 先放2*2
a[1] -= use2
a[0] = max(0, a[0] - (space4 - use2) * 4) # 剩余放1*1
# 处理3*3的箱子
ans += (a[2] + 3) // 4 # 每4个3*3一个箱子
rem3 = (4 - a[2] % 4) % 4 # 3*3剩余空间
if rem3 > 0:
space3 = rem3 * 9 # 剩余空间
use2_3 = min(a[1], space3 // 4) # 放2*2
a[1] -= use2_3
a[0] = max(0, a[0] - (space3 - use2_3 * 4)) # 剩余放1*1
# 处理2*2的箱子
ans += (a[1] + 8) // 9 # 每9个2*2一个箱子
rem2 = (9 - a[1] % 9) % 9 # 2*2剩余空间
if rem2 > 0:
a[0] = max(0, a[0] - rem2 * 4) # 剩余放1*1
# 处理1*1的箱子
ans += (a[0] + 35) // 36 # 每36个1*1一个箱子
print(ans)
def main():
while True:
a = list(map(int, input().split()))
if all(x == 0 for x in a):
break
solve(a)
if __name__ == "__main__":
main()
算法及复杂度
- 算法:贪心
- 时间复杂度:,每个测试用例的处理时间是常数
- 空间复杂度:,只需要固定大小的数组