T603362 烹饪
-
输入处理:
-
读取菜品数量
n。 -
读取每道菜品的烹饪时间,并计算总烹饪时间
sum。
-
-
特殊情况处理:
-
如果只有一道菜,直接输出该菜的烹饪时间。
-
-
动态规划初始化:
-
f[0] = 1表示容量为0的背包可以恰好装满(即不选任何菜品)。 -
sum /= 2将总时间的一半作为背包的容量上限,用于寻找最优分配方案。
-
-
动态规划处理:
-
使用01背包问题的思路,
f[j]表示是否存在一个子集,其烹饪时间和恰好为j。 -
遍历每道菜品,更新
f[j]的值。
-
-
结果查找:
-
从
sum向下查找最大的j,使得f[j]为1,即最大的不超过sum/2的子集和。 -
输出两个烤箱中较长的烹饪时间,即总时间减去
j。
-
#include<bits/stdc++.h> using namespace std; const int N = 1e6+10; // 定义足够大的数组大小,用于动态规划 int n; // 菜品数量 int a[N],f[N]; // a数组存储每道菜品的烹饪时间,f数组用于动态规划 int sum; // 所有菜品烹饪时间的总和 int main() { // 输入处理 cin >> n; for(int i = 1; i <= n; i++) { cin >> a[i]; // 读取每道菜品的烹饪时间 sum += a[i]; // 计算总烹饪时间 } // 特殊情况处理:如果只有一道菜,直接输出该菜的烹饪时间 if(n == 1){ cout << a[1]; return 0; } int s = sum; // 保存总烹饪时间 sum /= 2; // 计算总时间的一半,用于背包问题的容量 // 动态规划初始化:f[0]表示容量为0时可以恰好装满 f[0] = 1; // 动态规划处理:01背包问题,计算能否恰好装满容量为j的背包 for(int i = 1; i <= n; i++) { for(int j = sum; j >= a[i]; j--) { f[j] |= f[j - a[i]]; // 状态转移方程 } } // 查找最大的j,使得f[j]为1,即最大的不超过sum/2的子集和 for(int j = sum; j >= 1; j--) { if(f[j]){ // 输出两个烤箱中较长的烹饪时间,即总时间减去j cout << s - j; return 0; } } return 0; }

浙公网安备 33010602011771号