zoukankan      html  css  js  c++  java
  • P2392 kkksc03考前临时抱佛脚题解

    题目传送门

    1、深度优先搜索

    #include <bits/stdc++.h>
    
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int res;            //每一科目试题时间总和
    int s[20 + 10];     //科目数量
    int a[60 + 10];     //每一道题目需要的时间
    
    int n;              //当前科目的试题数量
    int m;              //当前科目完成试题的最短时间
    
    /**
     * 功能:本科目的试题,dfs跑所有情况。
     * @param ans   当前选择路线上的时间长度值
     * @param step  正在处理第几个试题
     * @param cnt   当前科目一共多少个试题
     */
    void dfs(int step, int ans) {
        //step从站在1位置开始,向下一个位置进行眺望,如果已经站在n的位置上了,就表示该进行总结了~
        if (step == n + 1) {
            //如果ans代表前一半的话,那么res-ans就代表另一半,这两半谁大就是这组方案的解
            m = min(m, max(ans, res - ans));//找出方案的最小值
            return;
        }
        //不要下一道题
        dfs(step + 1, ans);
        //要上下一道题
        dfs(step + 1, ans + a[step + 1]);
    }
    
    int main() {
        //读入四科的题目数量
        for (int i = 1; i <= 4; i++) cin >> s[i];
        int sum = 0;
    
        //遍历每一科,进行试题处理
        for (int i = 1; i <= 4; i++) {
            //本科目的所有试题总时长
            res = 0;
            //初始化数组
            memset(a, 0, sizeof a);
            //读入试题需要的时间
            for (int j = 1; j <= s[i]; j++) {
                cin >> a[j];
                res += a[j];//计算总的时长
            }
            //当前科目的试题数量
            n = s[i];
            //逐科目开始找出最短的复习时间
            m = INF;//预求最小,先设最大
            //暴搜
            dfs(1, 0);
            //暴搜的结果在m里,把m加到总和中
            sum += m;
        }
        //输出总和
        cout << sum << endl;
        return 0;
    }
    
    

    2、01背包

    #include <bits/stdc++.h>
    
    using namespace std;
    int s1, s2, s3, s4; //4科的题目数量
    
    //20是每个科目的题目数量上限
    //60是每道题消耗的最长时间上限
    //题目数据上限为20*60,这里设置为1210,保证不会越界
    const int N = 610; //背包的最大容量是 20*60,我们设置1200就可以,但实际上我们只需要一半的容量,就是610就行了。
    int w[N], v[N], f[N];
    
    int bag(int n) {
        int sum = 0; //当前科目中所有习题的时长总和
        memset(f, 0, sizeof(f));
    
        for (int i = 1; i <= n; i++) {
            cin >> w[i];
            v[i] = w[i]; //此题中的价值v和重量w是同一个概念,背包上限的是总时间的一半,放入一个习题,就占用了v[i]的时间,产生了v[i]的价值
            sum += w[i]; //总时长
        }
        //总时长的一半,就是尽量想办法装满一半的容量
        int m = sum / 2;
    
        //01背包模板
        for (int i = 1; i <= n; i++)
            for (int j = m; j >= w[i]; j--) // sum/2就是背包的上限,因为一半尽量装满,则不是这半最佳就是另一半最佳。
                f[j] = max(f[j], f[j - w[i]] + v[i]);
    
        //两半取最大的一半就是本科目的时长
        return max(f[m], sum - f[m]);
    }
    
    int main() {
        //需要考4科
        cin >> s1 >> s2 >> s3 >> s4;
        int ans = bag(s1) + bag(s2) + bag(s3) + bag(s4); //一科一科的整,四个背包最优解的总和
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    数据结构的基本概念
    react 组件生命周期
    设计模式
    MySQL processlist/kill
    大数据新手之路四:联合使用Flume和Kafka
    大数据新手之路三:安装Kafka
    大数据新手之路二:安装Flume
    大数据新手之路一:安装JDK
    tmux常用快捷键
    (转)Linux下设置和查看环境变量
  • 原文地址:https://www.cnblogs.com/littlehb/p/15062072.html
Copyright © 2011-2022 走看看