T603362 烹饪

  1. 输入处理

    • 读取菜品数量n

    • 读取每道菜品的烹饪时间,并计算总烹饪时间sum

  2. 特殊情况处理

    • 如果只有一道菜,直接输出该菜的烹饪时间。

  3. 动态规划初始化

    • f[0] = 1表示容量为0的背包可以恰好装满(即不选任何菜品)。

    • sum /= 2将总时间的一半作为背包的容量上限,用于寻找最优分配方案。

  4. 动态规划处理

    • 使用01背包问题的思路,f[j]表示是否存在一个子集,其烹饪时间和恰好为j

    • 遍历每道菜品,更新f[j]的值。

  5. 结果查找

    • 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;
}

 

posted @ 2025-04-28 18:09  CRt0729  阅读(16)  评论(0)    收藏  举报