• 【洛谷 P2392】kkksc03考前临时抱佛脚 题解(动态规划+01背包)


    kkksc03考前临时抱佛脚

    题目背景

    kkksc03 的大学生活非常的颓废,平时根本不学习。但是,临近期末考试,他必须要开始抱佛脚,以求不挂科。

    题目描述

    这次期末考试,kkksc03 需要考 4 4 4 科。因此要开始刷习题集,每科都有一个习题集,分别有 s 1 , s 2 , s 3 , s 4 s_1,s_2,s_3,s_4 s1,s2,s3,s4 道题目,完成每道题目需要一些时间,可能不等( A 1 , A 2 , … , A s 1 A_1,A_2,\ldots,A_{s_1} A1,A2,,As1 B 1 , B 2 , … , B s 2 B_1,B_2,\ldots,B_{s_2} B1,B2,,Bs2 C 1 , C 2 , … , C s 3 C_1,C_2,\ldots,C_{s_3} C1,C2,,Cs3 D 1 , D 2 , … , D s 4 D_1,D_2,\ldots,D_{s_4} D1,D2,,Ds4)。

    kkksc03 有一个能力,他的左右两个大脑可以同时计算 2 2 2 道不同的题目,但是仅限于同一科。因此,kkksc03 必须一科一科的复习。

    由于 kkksc03 还急着去处理洛谷的 bug,因此他希望尽快把事情做完,所以他希望知道能够完成复习的最短时间。

    输入格式

    本题包含 5 5 5 行数据:第 1 1 1 行,为四个正整数 s 1 , s 2 , s 3 , s 4 s_1,s_2,s_3,s_4 s1,s2,s3,s4

    2 2 2 行,为 A 1 , A 2 , … , A s 1 A_1,A_2,\ldots,A_{s_1} A1,A2,,As1 s 1 s_1 s1 个数,表示第一科习题集每道题目所消耗的时间。

    3 3 3 行,为 B 1 , B 2 , … , B s 2 B_1,B_2,\ldots,B_{s_2} B1,B2,,Bs2 s 2 s_2 s2 个数。

    4 4 4 行,为 C 1 , C 2 , … , C s 3 C_1,C_2,\ldots,C_{s_3} C1,C2,,Cs3 s 3 s_3 s3 个数。

    5 5 5 行,为 D 1 , D 2 , … , D s 4 D_1,D_2,\ldots,D_{s_4} D1,D2,,Ds4 s 4 s_4 s4 个数,意思均同上。

    输出格式

    输出一行,为复习完毕最短时间。

    样例 #1

    样例输入 #1

    1 2 1 3		
    5
    4 3
    6
    2 4 3
    
    • 1
    • 2
    • 3
    • 4
    • 5

    样例输出 #1

    20
    
    • 1

    提示

    1 ≤ s 1 , s 2 , s 3 , s 4 ≤ 20 1\leq s_1,s_2,s_3,s_4\leq 20 1s1,s2,s3,s420

    1 ≤ A 1 , A 2 , … , A s 1 , B 1 , B 2 , … , B s 2 , C 1 , C 2 , … , C s 3 , D 1 , D 2 , … , D s 4 ≤ 60 1\leq A_1,A_2,\ldots,A_{s_1},B_1,B_2,\ldots,B_{s_2},C_1,C_2,\ldots,C_{s_3},D_1,D_2,\ldots,D_{s_4}\leq60 1A1,A2,,As1,B1,B2,,Bs2,C1,C2,,Cs3,D1,D2,,Ds460


    思路

    在每个科目的循环中,计算每个科目的学习总时间 sum,并遍历每个学习时间,使用当前学习时间更新 dp 数组。

    状态转移方程

    dp[k] = max(dp[k], dp[k - hw[j]] + hw[j]);
    
    • 1

    当每个科目左脑时间与右脑时间尽量接近时,总时间最小。

    最后,累加每科所有作业总时间减去 dp[sum/2] 的值,得到完成所有科目的最短总时间。


    AC代码

    #include 
    #include 
    #include 
    #define AUTHOR "HEX9CF"
    using namespace std;
    
    const int N = 1e4 + 5;
    
    int ans;
    int s[5], hw[N];
    
    int main()
    {
        for (int i = 0; i < 4; i++)
        {
            cin >> s[i];
        }
        for (int i = 0; i < 4; i++)
        {
            int sum = 0;
            int dp[N];
            for (int j = 0; j < s[i]; j++)
            {
                cin >> hw[j];
                sum += hw[j];
            }
            memset(dp, 0, sizeof(dp));
            for (int j = 0; j < s[i]; j++)
            {
                for (int k = sum / 2; k >= hw[j]; k--)
                {
                    dp[k] = max(dp[k], dp[k - hw[j]] + hw[j]);
                }
            }
            ans += sum - dp[sum / 2];
        }
        cout << ans << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    Echarts ----写属性设置
    vue前后端端口不一致解决方案
    prettytable:一款像数据库一样可完美格式化输出的 Python 库
    甲基咪唑离子液体[MIM]Cl修饰Fe3O4@SiO2磁性纳米颗粒(Fe3O4@SiO2@[MIM]Cl)采用硅烷化法制备
    java.sql.SQLSyntaxErrorException: Unknown database ‘数据库名‘
    java实现线程安全的三种方式
    paddleocr关闭log日志打印输出
    什么是快速失败(fail-fast)和安全失败(fail-safe)?
    1000万条数据分页方法,redis提高访问速度,减少数据库压力
    服务器为什么会丢包
  • 原文地址:https://blog.csdn.net/qq_34988204/article/details/133580828