(C++)带权区间调度(Weighted Interval Scheduling)(动态规划)

写在所有的前面:

本文采用C++实现代码

题目说明

题目:带权区间调度(Weighted Interval Scheduling)

题目出处

广西大学oj
22级《算法设计与分析》第二次课堂作业
https://oj.gxu.edu.cn/contest/625/problem/0004

题目描述Description

背每一个任务都有三个属性:开始时间s、结束时间f以及所产生的价值v一个任务的s到f这段时间称为其执行时间,如果两个任务的执行时间不重叠,则称它们是兼容的本题将给出若干任务及其属性,求彼此兼容且权重最大的任务子集,输出该子集所有任务产生的总价值。

输入Input

输入有1+n行;第1行为任务数量;剩余n行每行为一个任务的开始时间、结束时间和所产生的价值,以空格隔开

输出Output

输出应为一个数,即彼此兼容且权重最大的任务子集中所有任务产生的总价值

样例Sample

输入:

4
1 2 50
3 5 20
6 19 100
2 100 200

输出:

250

限制Hint

解答说明

方案1:动态规划

解题思路

背包问题的变种:本人写的《(C++)0-1背包问题(动态规划)》
https://blog.csdn.net/just_do_it_sq/article/details/142499586?spm=1001.2014.3001.5501
总共n个任务,m时间最大值(终止时间数组 f 的最大值作为所有任务的终止时间)
通过 sumv[i][j] 记录执行前 i 个任务,时间为 j 时,所拥有的最大总价值
遍历每一个 i 和 j 来实现对 sumv 的填充
最后输出 sumv[n][m] 即可

一般情况

当任务 i 无法被执行完毕时j < f[i],和执行上一个任务时一样sumv[i][j] = sumv[i - 1][j];
否则掏出对应执行时间的任务,查看当时的最大总价值 + 当前任务价值 与 执行上一任务方案相比,哪个更总价值更大sumv[i][j] = max(sumv[i - 1][j], sumv[i - 1][s[i]] + v[i]);

特殊情况

初始化:没有任务( i == 0 )和没有时间( j == 0 )时,sumv 为 0

代码实现

#include<iostream>
#include <algorithm>
using namespace std;

const int N = 100;//常量
int n;//任务数量
int s[N], f[N], v[N];//开始时间,结束时间,价值
int sumv[N][100 * N];//最大总价值,max[i][j] 代表执行前 i 个任务,时间为 j 时

int main()
{
	//输入数据
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d%d%d", &s[i], &f[i], &v[i]);
	}

	//终止时间数组 f 的最大值作为所有任务的终止时间
	int m = *max_element(f + 1, f + 1 + n);

	//计算最大总价值
	for (int i = 1; i <= n; i++) //执行前 i 个任务
	{
		for (int j = 1; j <= m; j++) //时间增大为 j
		{
			if (j < f[i])//执行不完
				sumv[i][j] = sumv[i - 1][j];//和执行上一件任务时一样
			else//装得进去
				//掏出对应时间的任务,查看当时的最大总价 + 当前任务价值 与 执行之前方案相比,哪个更总价更大
				sumv[i][j] = max(sumv[i - 1][j], sumv[i - 1][s[i]] + v[i]);
		}
	}
	//全部任务全部时间时最大价值
	printf("%d", sumv[n][m]);

	return 0;
}

其他解释

求数组最大值

*max_element(arr + m, arr + n),调用头文件#include <algorithm>,返回两个指针间数据的最大值,即arr[m]到arr[n]之间的最大值,最小值将max换为min即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值