贪心算法——赶作业(C++)

news2025/1/21 2:49:12

慢慢来,沉稳一点。

2024年6月18日


题目描述

        A同学有n份作业要做,每份作业有一个最后期限,如果在最后期限后交作业就会扣分,现在假设完成每份作业都需要一天。A同学想安排作业顺序,把扣分降到最低,请帮他实现。

输入格式

        包含t个测试用例,第一行是单个整数t。每个测试用例以一个正整数n开头,表示作业的数量,然后是两行;第一行包含n个整数,表示作业的截至日期;下一行包含n个整数,表示作业未完成需要扣的分数。

输出格式

        输出扣的最少分数即可。

输入样例:

2

3

3    3  3

10  5  1

7

1 4 6 4 2 4 3

3 2 1 7 6 5 4

输出样例:

0

5


题解思路

        贪心法——带惩罚的调度问题

        利用贪心思想,想让扣的分最低,肯定是先做那些扣分最多的作业,尽可能地保持剩下的作业即使没能完成也可以让扣的分最小化,那第一步就是对作业按扣的分数从大到小排序了,那下一步干什么呢?是不是需要确定做作业的顺序了。

        如果你觉得有疑问,不是已经按惩罚大小排序了吗,那先把惩罚最大的做完不就行了?

        NO!!!

        如果你是学生,你一般来说都是什么时候完成作业的呢?

        欸,知道了吧,是不是deadline呢?就算扣分很严重,我们依然保持在最后一天做完不就行了嘛,对吧。

        贪心的关键就在这:在排序完之后,我们每次都在截至时间或者靠近截至时间的某个时间完成作业就OK了,这样既能保证扣分大的作业顺利完成,扣分小的作业也能尽可能的完成了。

        那这样是不是就能保证扣的分最小呢?

(好好想想哦,后续我会更新这篇博客,添加证明,大家可以在提出自己的看法)


以上面的第个例子为例:

作业截至:1 4 6 4 2 4 3

惩罚分数:3 2 1 7 6 5 4

1. 按惩罚分数排序得到:

作业截至:4 2 4 3 1 4 6

惩罚分数:7 6 5 4 3 2 1

2. 下面用i表示当前的作业,days数组用于记录那一天做哪一样作业(days初始化为false),ans表示扣分(初始化为0):

  • i = 0时,其截至时间为4,选择在第4天完成该作业,days[4] = true,不用惩罚,ans = 0;
  • i = 1时,其截至时间为2,选择在第2天完成该作业,days[2] = true,不用惩罚,ans = 0;
  • i = 2时,其截至时间为4,第4天已经规划做作业0了,那就提前一天,选择在第3天完成该作业,days[3] = true,不用惩罚,ans = 0;
  • i = 3时,其截至时间为3,第3天已经规划做作业2了,如果提前一天,第二天同样也安排了做作业1,那就提前两天,days[1] = true,不用惩罚,ans = 0;
  • i = 4时,其截至时间为1,从前面看来前四天都安排了任务,尽可能地做扣分大的了,那么当前就不能完成该作业了,需要惩罚,ans = 3;
  • i = 5时,其截至时间为4,和作业4相同情况,没有可以安排的时间了,需要惩罚,ans = 3+2 = 5;
  • i = 6时,其截至时间为6,选择在第6天完成该作业,days[6] = true,不用惩罚,ans = 5;

这样写,你通透了吗?


代码实现

1. 定义homework结构体,利用在结构体里面重载函数完成排序;

struct homework{
    int deadline;
    int punish;
    homework(int deadline, int punish):deadline(deadline), punish(punish) {}
    bool operator<(const homework &s) const{
        return punish >= s.punish;
    }
};

2. 定义贪心函数getMinLoss;

int getMinLoss(vector<homework> &v){
    sort(v.begin(), v.end());

    int ans = 0;
    int flag[100];
    int len = v.size();

    memset(flag, 0, sizeof(flag));

    for(int i = 0; i < len; i++){
        if(flag[v[i].deadline] == 0){
            flag[v[i].deadline] = 1;
        }
        else{
            int tmp = v[i].deadline;
            while(flag[tmp]){
                tmp--;
            }
            if(tmp == 0){
                ans += v[i].punish;
            }
            else{
                flag[tmp] = 1;
            }
        }
    }
    return ans;
}

3. 完整代码如下:

// 带惩罚的调度问题

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>

using namespace std;

struct homework{
    int deadline;
    int punish;
    homework(int deadline, int punish):deadline(deadline), punish(punish) {}
    bool operator<(const homework &s) const{
        return punish >= s.punish;
    }
};

int getMinLoss(vector<homework> &v){
    sort(v.begin(), v.end());

    int ans = 0;
    int flag[100];
    int len = v.size();

    memset(flag, 0, sizeof(flag));

    for(int i = 0; i < len; i++){
        if(flag[v[i].deadline] == 0){
            flag[v[i].deadline] = 1;
        }
        else{
            int tmp = v[i].deadline;
            while(flag[tmp]){
                tmp--;
            }
            if(tmp == 0){
                ans += v[i].punish;
            }
            else{
                flag[tmp] = 1;
            }
        }
    }
    return ans;
}

int main(){
    cout<<"开始输入数据!!!";
    int t;
    cin>>t;
    vector<int> res;
    for(int i = 0; i < t; i++){
        int n;
        cin>>n;
        vector<homework> v;
        vector<int> Deadline;
        vector<int> Punish;
        // 输入数据
        for(int i = 0; i < n; i++){
            int deadline;
            cin>>deadline;
            Deadline.emplace_back(deadline);
        }
        for(int i = 0; i < n; i++){
            int punish;
            cin>>punish;
            Punish.emplace_back(punish);
        }
        // 初始化homework
        for(int i = 0; i < n; i++){
            v.emplace_back(homework(Deadline[i], Punish[i]));
        }
        // 将每次的结果插入结果集
        res.emplace_back(getMinLoss(v));
    }
    // 打印结果
    int count = 1;
    for(auto e:res){
        cout<<"第"<<count<<"次最多扣"<<e<<"分"<<endl;
        count++;
    }
    return 0;
}

// 2
// 3
// 3 3 3
// 10 5 1
// 7
// 1 4 6 4 2 4 3
// 3 2 1 7 6 5 4
// 0
// 5

4. 运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1837808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为OD机试 - 聚餐地点 - 广度优先搜索BFS(Java 2024 D卷 200分)

华为OD机试 2024D卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测…

美联储的秘密议程 Fed's Hidden Agenda

编译 | 刘教链 教链按&#xff1a;本文是来自“米塞斯学院”Ryan McMaken的稿子&#xff0c;原标题是「美联储“软着陆”叙事背后的真实故事&#xff08;The Real Story Behind the Fed’s “Soft Landing” Narrative&#xff09;」。昨{2024.6.17内参&#xff1a;战报会骗人&…

实验1_配置标准IPv4 ACL

1、实验目的 通过本实验可以掌握&#xff1a; IPv4 ACL工作方式和工作过程定义编号和命名的标准IPv4 ACL的方法接口和VTY下应用标准IPv4 ACL的方法 2、实验拓扑 配置IPv4 ACL的实验拓扑如图9-2所示 配置 ACL 实验拓扑如下图所示。本实验中&#xff0c;通过配置标准 ACL 实现…

无痛接入图像生成风格迁移能力:GAN生成对抗网络

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…

QT基础 - 布局管理器间隔控件

目录 一. QVBoxLayout 二. QHBoxLayout 三. QGridLayout 四. QFormLayout 五. Spacers 六.总结 一. QVBoxLayout QVBoxLayout 主要用于将控件在垂直方向上进行排列。 它具有以下特点&#xff1a; 可以方便地管理和组织控件&#xff0c;使其按照垂直顺序依次排列。能够自动…

视频批量剪辑利器:轻松掌握尺寸修改技巧,支持自定义及预设尺寸,提升剪辑效率!

在数字化时代&#xff0c;视频已经成为我们生活中不可或缺的一部分。无论是社交媒体上的短视频&#xff0c;还是公司宣传的长视频&#xff0c;都离不开精心剪辑与处理。然而&#xff0c;对于很多小伙伴来说&#xff0c;视频剪辑仍然是一项既耗时又耗力的任务。尤其是当需要处理…

算法训练营第六十天(延长12天添加图论) | LeetCode 647 回文子串、LeetCode 516 最长回文子序列

LeetCode 67 回文子串 思路很简单&#xff0c;每一个dp[i]等于dp[i-1]加上当前字符向前直到0各个长度字符串回文串个数即可 代码如下&#xff1a; class Solution {public boolean isValid(String s) {int l 0, r s.length() - 1;while (l < r) {if (s.charAt(l) ! s.ch…

钡铼技术BL104在环境监测站多协议采集保障数据全面准确

随着工业化和城市化进程的加快&#xff0c;环境污染问题日益严重&#xff0c;环境监测站在保护生态环境、保障公众健康中的作用变得越来越重要。钡铼技术PLC物联网关BL104&#xff0c;为环境监测站提供了一种高效、可靠的多协议数据采集解决方案&#xff0c;保障了监测数据的全…

Multisim软件仿真之频谱分析仪

网络上有很多Multisim文件&#xff0c;有些是不能复现的&#xff0c;比如频谱仪&#xff0c;按照下面链接去操作&#xff0c;怎么也测试不出来波形&#xff0c;multisim频谱仪使用_multisim输入输出端口-CSDN博客。 原因分析&#xff1a; 1、博主设置参数未讲全&#xff0c;按…

sprintboot依赖管理和自动配置

springboot依赖管理和自动配置 依赖管理和自动配置依赖管理什么是依赖管理修改自动仲裁/默认版本号 starter场景启动器starter场景启动器基本介绍官方提供的starter第三方starter 自动配置自动配置基本介绍SpringBoot自动配置了哪些?如何修改默认配置如何修改默认扫描包结构re…

APP渗透、WIFI近源渗透之透明代理下的流量分析与嗅探

APP渗透、WIFI近源渗透之透明代理下的流量分析与嗅探 原文链接&#xff1a;https://xz.aliyun.com/t/14864 前言 在攻防中对APP进行渗透时可能会遇到代理及VPN的检测&#xff0c;以及在近源渗透时可能会有WIFI钓鱼的需求&#xff0c;而透明代理是一个很好的解决方案&#xf…

完整迁移方案+工具:Citrix替换,无感迁移!

随着用户的替换进程进入到演进的阶段&#xff0c;用户面临的重大挑战包括&#xff1a; &#xff08;1&#xff09;大量数据的迁移需要精确规划&#xff0c;以避免数据丢失或损坏&#xff1b; &#xff08;2&#xff09;迁移效率低下&#xff0c;不仅会增加迁移成本&#xff0c;…

深度解读等保2.0标准

在数字经济时代&#xff0c;信息安全已成为一个不容忽视的问题&#xff0c;其中&#xff0c;等级保护机制也是一个不断演化的过程。近几年&#xff0c;国内发生了一次重要的变化&#xff0c;就是等保2.0标准的颁布和执行。文章对该协议2.0进行了详细的阐述&#xff0c;并对其在…

波兰媒体海外宣发:波兰媒体投放助力企业在波兰力挽狂澜-大舍传媒

引言 在全球化的背景下&#xff0c;企业对海外市场的开拓变得愈发重要。波兰作为中东欧地区的重要经济体之一&#xff0c;吸引了越来越多的企业眼球。在这一过程中&#xff0c;波兰媒体的海外宣发起到了关键作用。本文将重点探讨大舍传媒、比得哥什日报和瓦维尔快讯这三家波兰…

记一次 .NET某机械臂上位系统 卡死分析

一&#xff1a;背景 1. 讲故事 前些天有位朋友找到我&#xff0c;说他们的程序会偶发性的卡死一段时间&#xff0c;然后又好了&#xff0c;让我帮忙看下怎么回事&#xff1f;窗体类的程序解决起来相对来说比较简单&#xff0c;让朋友用procdump自动抓一个卡死时的dump&#x…

macOS vscode常用快捷键

1、shiftoption上下箭头 复制当前行 2、commandd 选定多个相同的单词 先双击选定一个单词&#xff0c;然后按下commandd 依次选中要修改的单词&#xff0c;直接修改即可 3、全局替换某个单词 comandh 4、快速定位到某一行 controlg 5、选中某个区域 shiftoption&#xff0c;然…

医学人工智能在“免疫组化”领域的最新研究进展|顶刊速递·24-06-19

小罗碎碎念 顶刊速递&#xff5c;AI免疫组化 今天分享的文献主题是——人工智能与免疫组化的结合。其实之前的推文中也偶尔会提到免疫组化相关的内容&#xff0c;但是一直没有出一期&#xff0c;系统的梳理一下这一部分内容在医学AI中的应用&#xff0c;所以这期推文便来完成…

LabVIEW在中国航天中的应用

​LabVIEW是一种系统设计平台及开发环境&#xff0c;由美国国家仪器公司&#xff08;NI&#xff09;开发。它在中国航天领域的应用非常广泛&#xff0c;涵盖了测试与测量、数据采集、控制系统设计等多个方面。以下是LabVIEW在中国航天中的几个主要应用实例&#xff1a; 1. 测试…

微信小程序笔记 二!

小程序的宿主环境 - 宿主环境简介 1. 什么是宿主环境 宿主环境&#xff08;host environment&#xff09;指的是程序运行所必须的依赖环境。例如&#xff1a; Android 系统和 iOS 系统是两个不同的宿主环境。安卓版的微信 App 是不能在 iOS 环境下运行的&#xff0c;所以&…

shell脚本 函数

函数 shell的函数 定义&#xff1a;将命令序列按照格式写在一起。格式指的是函数的固定格式。两种格式。 for i in {} do 命令序列 done if [ ] then 命令序列 fi 作用&#xff1a;方便重复使用。函数库&#xff0c;集中在一起&#xff0c;随时可以传参调用。大的工…