0
点赞
收藏
分享

微信扫一扫

动规(13)-数据包的调度机制&山区建小学(试改成轮换数组)

目录

一、数据包的调度机制

二、山区建小学(试改成轮换数组)


一、数据包的调度机制

描述

随着 Internet的迅猛发展,多媒体技术和电子商务应用日益广泛,Internet上的服务质量

(QoS,Qualityof Service)问题已越来越受到重视。网络中采用的数据包调度机制与网络的服务质量 QoS 有着密切的关系。研究表明传统的基于队列的调度机制已不能满足网络服务质量QoS 的需求。服务质量 QoS 取决于数据包的延迟。每一个数据包都有一个延迟惩罚值。由于数据包承载的数据不同,不同数据包的延迟惩罚值也可能不同。此外,数据包的延迟也和它的发送顺序有关。如果一个数据包被第K个发送,假设它的延迟惩罚值是D,则这个数据包的最终延迟是 (K - 1) * D。北京大学2012 级信息学院的同学在程序设计课堂上,设计了一种新的基于栈的数据包的调度算法。同学们通过栈的先进后出(Last in First out)的原理,改变数据包的发送顺序,以减小数据包的延迟总值。给定N 个等待调度的数据包,起始这N 个数据包排成一个队列等待发送。接着,这些数据包按序进栈,调度算法可以控制数据包的出栈顺序。因此通过栈,可以将后面的数据包先于前面的数据包发送出去。请你实现一个调度算法使N 个数据包的延迟总值最小。

输入

输出

样例输入

样例输出

#include <iostream>
using namespace std;
int n, k, t, ans;
int v[105], sum[105], f[105][105];
int main()
{
	cin >> t;
	while (t--)
	{
		cin >> n;
		for (int i = 1; i <= n; i++)
			cin >> v[i], sum[i] = sum[i - 1] + v[i];
		for (int len = 2; len <= n; len++)
			for (int i = 1; i + len - 1 <= n; i++)
			{
				f[i][len] = 0x7fffffff;
				for (int k = i; k <= i + len - 1; k++)
					f[i][len] = min(f[i][len], f[i][k - i] + v[k] * (len - 1) + f[k + 1][i + len - k - 1] + (sum[i + len - 1] - sum[k]) * (k - i));
			}					 //对于进栈的三段,出栈有132、123、312、321以上四种合并都包括,上面是132形式!
		cout << f[1][n] << endl; // 231这种形式在栈中不可能出现
	}
	return 0; // 3  19  6  7结果为19
}

题解

二、山区建小学(试改成轮换数组)

描述

政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往。已知任意两个相邻的村庄之间的距离为di(为正整数),其中,0 < i < m。为了提高山区的文化素质,政府又决定从m个村中选择n个村建小学(设 0 < n < = m < 500 )。请根据给定的m、n以及所有相邻村庄的距离,选择在哪些村庄建小学,才使得所有村到最近小学的距离总和最小,计算最小值。

输入

第1行为m和n,其间用空格间隔
第2行为(m-1) 个整数,依次表示从一端到另一端的相邻村庄的距离,整数之间以空格间隔。
例如
10 3
2 4 6 5 2 4 3 1 3
表示在10个村庄建3所学校。第1个村庄与第2个村庄距离为2,第2个村庄与第3个村庄距离为4,第3个村庄与第4个村庄距离为6,...,第9个村庄到第10个村庄的距离为3。

输出

各村庄到最近学校的距离之和的最小值。

样例输入

10 2

3 1 3 1 1 1 1 1 3

样例输出

18

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n, m, x;
int dp[501][501], s[501], sum[501][501];
int main()
{
	scanf("%d%d", &n, &m);
	memset(dp, 0x7f, sizeof(dp));
	for (int i = 2; i <= n; i++)
	{
		scanf("%d", &s[i]);
		s[i] = s[i - 1] + s[i];
	} //前缀和
	for (int i = 1; i < n; i++)
		for (int j = i + 1; j <= n; j++)
			sum[i][j] = sum[i][j - 1] + s[j] - s[(i + j) / 2]; // c处理出任意两点间建一所小学所需路程和(中点原理)
	for (int i = 1; i <= n; i++)
		dp[1][i] = sum[1][i];
	for (int k = 2; k <= m; k++)
		for (int i = k; i <= n; i++)
			for (int j = k - 1; j < i; j++)
				dp[k][i] = min(dp[k][i], sum[j + 1][i] + dp[k - 1][j]);
	printf("%d\n", dp[m][n]); //最后区间dp
	return 0;
}
举报
0 条评论