网站改标题彩票网站建设平台
web/
2025/10/4 6:05:12/
文章来源:
网站改标题,彩票网站建设平台,展示型网站与营销型网站,从您的角度来看_对于农产品网站的建设有什么想法或建议呢?第四次作业【贪心算法】 文章目录 第四次作业【贪心算法】1 算法分析题4-1 会场安排问题2 算法实现题4-9 虚拟汽车加油问题3 算法实现题4-13 非单位时间任务安排问题4 算法实现题4-14 多元Huffman编码问题 1 算法分析题4-1 会场安排问…第四次作业【贪心算法】 文章目录 第四次作业【贪心算法】1 算法分析题4-1 会场安排问题2 算法实现题4-9 虚拟汽车加油问题3 算法实现题4-13 非单位时间任务安排问题4 算法实现题4-14 多元Huffman编码问题 1 算法分析题4-1 会场安排问题
▲问题重述
假设要在足够多的会场里安排一批活动并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数相应于要找的最小会场数。 对于给定的k个待安排的活动计算使用最少会场的时间表。
Input 输入数据的第一行有1 个正整数kk≤10000表示有k个待安排的活动。接下来的k行中每行有2个正整数分别表示k个待安排的活动开始时间和结束时间。时间以0 点开始的分钟计。
Output 输出一个整数表示最少会场数。
Sample Input
5
1 23
12 28
25 35
27 80
36 50
Sample Output
3▲想法
先按照开始时间递增排序若开始时间相同则按照结束时间递增排序。每次都优先安排序号靠前的活动除非不相容一遍扫完之后再扫第二遍同时开第二个会场直至所有活动都被安排。
▲代码
// -*- coding:utf-8 -*-// File : 4-1 会场安排问题.cpp
// Time : 2023/12/29
// Author : wolf#include algorithm
#include iostreamusing namespace std;
struct activity
{int start;int end;bool if_arrange;
} a[10001];bool cmp(struct activity a, struct activity b)
{if (a.start b.start)return 1;else if (a.start b.start){if (a.end b.end)return 1;}return 0;
}int main()
{int k;cin k;for (int i 0; i k; i){cin a[i].start a[i].end;a[i].if_arrange 0;}sort(a, a k, cmp);int ok_num 0; // 已安排成功的会场数量int now_end 0; // 当前安排的活动的结尾时间int ans 0; // 要开的会场数目while (ok_num k){now_end 0;ans;for (int i 0; i k; i){if (a[i].if_arrange 0){if (a[i].start now_end) // 相容可加入{a[i].if_arrange 1;ok_num;now_end a[i].end;}}}}cout ans endl;return 0;
}
▲验证
测试数据一样例
输入
5
1 23
12 28
25 35
27 80
36 50 输出
3测试数据二
输入
14
34 99
53 57
19 75
11 95
50 76
33 76
61 74
22 69
16 28
7 44
23 92
14 65
7 19
36 52输出
9测试数据三
输入
57
71 73
23 41
1 78
39 74
6 76
31 63
0 74
64 82
15 46
65 69
5 19
64 71
15 71
23 29
10 42
4 77
15 16
29 52
50 71
60 63
32 87
16 47
50 61
42 94
1 29
86 91
9 22
10 71
31 87
13 88
44 49
7 43
62 96
20 71
6 57
22 24
68 92
66 94
32 83
18 77
79 97
53 83
6 8
31 81
42 98
72 90
27 42
13 64
33 93
2 34
17 29
29 70
18 88
7 54
11 23
3 46
30 89输出
302 算法实现题4-9 虚拟汽车加油问题
▲问题重述
问题描述一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法指出应在哪些加油站停靠加油使沿途加油次数最少。对于给定的n(n 5000)和k(k 1000)个加油站位置编程计算最少加油次数。并证明算法能产生一个最优解。
算法设计对于给定的n和k个加油站的位置计算最少的加油次数。
数据输入第一行有两个正整数n和k表示汽车加油后可行驶n km且旅途中有k个加油站。接下来的一行中有k1个整数表示第k个加油站和第k-1个加油站之间的距离。 结果输出将计算的最少加油次数输出如果无法到达目的地则输出“No Solution”。
▲想法
对于到达每一个加油站时的处理如果目前的油够到达下一站就不再加油了把油留到后面加如果目前的油不够到达。
▲代码
// -*- coding:utf-8 -*-// File : 4-9 虚拟汽车加油问题.cpp
// Time : 2023/12/29
// Author : wolf#include iostreamusing namespace std;int main()
{int n, k, temp;cin n k;int rest_oil n;cin temp; // 读入第一个加油站不做处理int ans 0;for (int i 0; i k; i){int now_input;cin now_input;if (now_input n){cout No Solution endl;return 0;// 到下一加油站的距离超过加满油能行驶的距离时不可行的。}if (rest_oil - now_input 0){rest_oil - now_input;}else{rest_oil n;rest_oil - now_input;ans;}}cout ans endl;return 0;
}
▲验证
输入
7 7
1 2 3 4 5 1 6 6 输出
43 算法实现题4-13 非单位时间任务安排问题
▲问题重述
问题描述和要求 具有截止时间和误时惩罚的任务安排问题可描述如下 1给定 n 个任务的集合 S{1,2,…,n} 2完成任务 i 需要 ti时间1≤i≤n 3任务 i 的截止时间 di1≤i≤n即要求任务 i 在时间 di之前结束 4任务 i 的误时惩罚 wi1≤i≤n即任务 i 未在时间 di之前结束将招致 wi 的惩罚若按时完成则无惩罚。
算法设计设计一个贪心选择思想与动态规划思想相结合的算法解决以上任务 安排问题确定 S 的一个最优时间表使得总误时惩罚达到最小。
数据输入首先输入一个正整数 n 表示任务的个数。接下来的 n 行中每行输入 三个整数分别代表相应任务需要的时间 ti截止时间 di以及误时惩罚 wi。
结果输出输出任务安排结果以及总的误时惩罚。
案例
input
7
1 4 70
2 2 60
1 4 50
1 3 40
1 1 30
1 4 20
3 6 80output
110▲想法
首先将仍无依照其截止时间非递减排序
设对于任务12……i。截止时间为d的最小误时惩罚为p[i][d]则p[i][d]符合最优子结构性质且有递推式
p[i][d] min{ p[i-1][d] w[i], p[i-1][min{d,d[i]} - t[i]] }边界条件有
考虑p[1][d]
对于 t[1] d 时截止时间大于完成任务的时间而且只有一个任务该任务是可以完成的所以没有惩罚。
对于 t[1] d 时由于第一个工作无法完成必然导致惩罚罚时为w[1]。
▲代码
// -*- coding:utf-8 -*-// File : 4-13 非单位时间任务安排问题.cpp
// Time : 2023/12/30
// Author : wolf#include algorithm
#include iostreamusing namespace std;
int const MAXINT 99999;
struct task
{int t; // cost timeint d; // deadlineint w; // weight
} task[1000];bool cmp(struct task a, struct task b)
{return a.d b.d;
}int main()
{int n;cin n;for (int i 0; i n; i){cin task[i].t task[i].d task[i].w;}sort(task, task n, cmp);int maxd task[n - 1].d;int dp[n][maxd 1]; // dp[i][j] 到第i个任务截止时间为j时的最小惩罚for (int i 0; i n; i){for (int j 0; j maxd; j){dp[i][j] MAXINT;}}for (int j 0; j maxd; j){if (j task[0].d)dp[0][j] task[0].w;elsedp[0][j] 0;}for (int i 1; i n; i){for (int j 0; j maxd; j){int drop dp[i - 1][j] task[i].w;dp[i][j] drop;if (min(j, task[i].d) - task[i].t 0){int fetch dp[i - 1][min(j, task[i].d) - task[i].t];dp[i][j] min(drop, fetch);}}}cout dp[n - 1][maxd] endl;// for (int i 0; i n; i)// {// for (int j 0; j maxd; j)// {// cout dp[i][j] ;// }// cout endl;// }return 0;
}
▲验证
input
7
1 4 70
2 2 60
1 4 50
1 3 40
1 1 30
1 4 20
3 6 80output
1104 算法实现题4-14 多元Huffman编码问题
▲想法
1求最大费用时只需将石堆排列后从大到小两两进行合并即可。 2求最小费用时将石堆排列后每次合并的石堆数为K堆。但有时会出现特例即每次合并K堆最后一次合并时无法以K堆进行合并这样合并的结果就不是最小费用了。所以就要先判断原总堆数是否能使每次合并的堆数都为K堆如果不能的话就要在原堆数前面加上 X 个“0”堆来补齐缺少的堆数.。 例如共7堆最大合并5堆 石子堆45 13 12 5 9 22 16 这时排序后5 9 12 13 16 22 45 如果先合并前5堆这样结果就为177 如果补零的话得到 0 0 5 9 12 13 16 22 45这时正好每次都合并5堆最后合并为1堆这时结果为148
编程思路
1分别创建一个递增的优先队列和一个递减的优先队列。创建队列的优点是可以对数字自动排序、取数等一些操作方便如q.top();表示取队首元素。 2对于递增队列① 先判断是否需要加“0”堆需要就加② 只要队列中的元素个数大于1等价于队列中还至少有k堆石子当然剩余石子堆数为k的整数倍就对队列前k个元素进行处理。每次将队首加入到sum中加完后就把队首弹出队列继续处理下一个队首直至处理了k个队首即合并了k堆石子。得到n个sum后将sum累加起来得到的就是最小费用。 3对于递减队列方法同二只是这里是连续处理2个队首。
▲代码
#include bits/stdc.h
using namespace std;int main()
{int n, k, x; // x为每堆石子数long long sum1 0, sum2 0; // sum1、sum2分别为最小总费用和最大总费用priority_queueint, vectorint, greaterint q1; // 创建递增的优先队列priority_queueint, vectorint, lessint q2; // 创建递减的优先队列cin n k;for (int i 0; i n; i) // 输入每堆石子数并压入优先队列中{cin x;q1.push(x);q2.push(x);}while (q1.size() % (k - 1) ! 1) // 判断q1能否每次合并k堆且恰好合并完q1.push(0); // 不能合并完就要压入“0”while (q1.size() 1){long long sum 0;for (int i 0; i k; i) // 每次都是队首前k堆合并{sum q1.top(); // 前k堆每堆的费用加入到临时变量sum中q1.pop(); // 队首的这堆石子合并后将它弹出队列}sum1 sum; // 将前k堆的费用加入到总费用中q1.push(sum); // 这个前k堆的费用压入队列中}while (q2.size() 1){long long sum 0;for (int i 0; i 2; i){sum q2.top();q2.pop();}sum2 sum;q2.push(sum);}cout sum2 sum1 endl;return 0;
}
▲验证
输入
7 3
45 13 12 16 9 5 22输出
593 199
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/86631.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!