当前位置: 首页 > news >正文

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

慢慢来,沉稳一点。

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);}// 初始化homeworkfor(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. 运行结果

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 14、modbus poll 使用教程小记1
  • iOS18新增通话录音和应用锁!附升级教程及内置壁纸
  • Blender下使用python设置骨骼旋转
  • Java进阶示例
  • 【100个C++面试题和解答】
  • 电脑怎么录音?分享2种音频录制方法
  • iOS 18 Siri 升级之后都有哪些改变?
  • Idea连接GitLab的过程以及创建在gitlab中创建用户和群组
  • 【无标题】蓝桥杯软件赛Java研究生组/A组)第二章基础算法-第四节:构造
  • WDF驱动开发-硬件资源(一)
  • ElasticSearch学习篇13_《检索技术核心20讲》进阶篇之LSM树
  • 【如何在Python中使用turtle库】
  • 小程序分页新写法
  • STM32开发过程中碰到的问题总结 - 3
  • 使用Unsloth微调Llama3-Chinese-8B-Instruct中文开源大模型
  • 「面试题」如何实现一个圣杯布局?
  • export和import的用法总结
  • JavaScript类型识别
  • java中的hashCode
  • Linux gpio口使用方法
  • Linux快速复制或删除大量小文件
  • Mocha测试初探
  • Redis 懒删除(lazy free)简史
  • Ruby 2.x 源代码分析:扩展 概述
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • 给github项目添加CI badge
  • 将 Measurements 和 Units 应用到物理学
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​ssh免密码登录设置及问题总结
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​什么是bug?bug的源头在哪里?
  • ![CDATA[ ]] 是什么东东
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • #LLM入门|Prompt#3.3_存储_Memory
  • #宝哥教你#查看jquery绑定的事件函数
  • (阿里云万网)-域名注册购买实名流程
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (正则)提取页面里的img标签
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • ./configure,make,make install的作用(转)
  • .net core 连接数据库,通过数据库生成Modell
  • .net core 外观者设计模式 实现,多种支付选择
  • .net 托管代码与非托管代码
  • .NET/C# 使窗口永不获得焦点
  • .net用HTML开发怎么调试,如何使用ASP.NET MVC在调试中查看控制器生成的html?
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • @component注解的分类
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节
  • []新浪博客如何插入代码(其他博客应该也可以)
  • [240727] Qt Creator 14 发布 | AMD 推迟 Ryzen 9000芯片发布
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [AI Embedchain] 开始使用 - 全栈