算法设计与分析 SCAU17104 视频流有效调度

news2024/10/7 20:25:49

17104 视频流有效调度

时间限制:1000MS 代码长度限制:10KB
提交次数:25 通过次数:9

题型: 编程题 语言: G++;GCC;VC;JAVA

在这里插入图片描述


Description

现在n个视频流要在一条通信链路上一个接一个的传送。视频流i由bi位组成,这些位需要一个常数速率,
在ti秒内被发送。你不可能同时发送两个视频流,因此需要确定一个关于视频流的调度。
无论你选择哪一个次序,在一个视频流的结束与下一个视频流开始之间不能有任何延迟。假如你调度在时
刻0开始,无论采用什么次序,都将结束于sum{ ti | i from 1 to n}这个时刻。我们假设所有的bi和ti都
是正整数。

现在引入一个链路限制参数r。由于你仅仅是一个用户,这个链路不想让你占用太多的带宽,因此规定这个限制
条件:对每个自然数t>0,你在从0到t的时间区间内发送的总位数不能超过rt。这个规定是对开始于0的时间区间
的,而不是开始于任何别的时间区间的。满足这个限制的调度才是有效的。

给定n个视频流,每个视频流位数bi,持续时间ti,以及链路限制参数r。比如,n=3个视频流,具有:
(b1,t1)=(2000,1)
(b2,t2)=(6000,2)
(b3,t3)=(2000,1)
链路限制参数r=5000。

则按照1,2,3的次序运行这个视频流的调度室有效的,因为:
t=1:第1个视频流全部被发送,且2000<50001
t=2:第2个视频流一半被发送,且2000+3000<5000
2
t=3与t=4,类似的结论也成立。

现在给出一个多项式运行时间的算法,确定是否存在一个有效调度?并输出这个有效调度。


输入格式

第一行:n r (n表示视频流个数,r表示链路限制参数,中间空格,n<10000,r>0)
接下来n行,都是这样组合:bi ti 1<=i<=n


输出格式

n个视频流有效的调度顺序(这个调度顺序不一定唯一,我们优先输出字典序排前的那一种调度)。
若不存在有效的调度顺序,输出“no”(无大写无标点)。


输入样例

3 5000
2000 1
6000 2
2000 1


输出样例

1 2 3


解题思路

1. 贪心算法

由于题目要求是 优先输出的是“字典序”最小的有效调度,所以贪心思想也是比较容易想到的,即:每次都从头往后找,找到第一个满足视频流调度条件的,就进行记录,然后重新从头往后找,直到所有视频流都记录为止(即所有视频流都已发送)。


算法思路

  1. 对输入的数据进行记录,并用变量 currentByte 记录当前视频流总字节数,用变量 currentClock 记录当前消耗的总时间单位数。
  2. 然后双循环,外层循环 i 记录当前已经记录的视频流个数,即要输出的数组的一个个元素。
  3. 内层循环为主要算法,j 从头往后遍历,如果该序号没被记录过(数组 v[i] 没被标记过),且满足视频流调度条件:加上该视频,字节也在链路带宽限制范围内。
  4. 找到视频后,就进行记录,然后继续循环,直到所有视频都记录为止。



更多注释可查看下方的完整代码中,有助于理解。

代码如下

#include <vector>
#include <utility>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

int byte[10001];
int Time[10001];
vector<int> num; // 存各视频流编号,即 cur,要输出的
int v[10001]; // v[i] 用于标记数字是否被选中

int main()
{
    int i, j, n, r;
    cin >> n >> r;

    for(i = 1; i <= n; i++) {
        cin >> byte[i] >> Time[i];
    }

    int currentByte = 0; // 当前视频流总数
    int currentClock = 0; // 当前消耗的时间单位数

    // 当前要输出的数组记录了几位编号了
    for(i = 1; i <= n; i++) {
        int flag = 0; // 用于表示本轮从头往后找,有无找到满足视频流调度的序号

        for(j = 1; j <= n; j++) {
            // 该视频流没被选过且加上该视频流后,字节还在范围内,即找到满足条件的视频流了
            if(!v[j] && currentByte + byte[j] <= (currentClock + Time[j]) * r) {
                v[j] = 1;
                flag = j;
                break;
            }
        }

        // 说明本轮从头往后找没找到满足视频流调度的序号,由于还没发完全部视频流,所以不满足
        if(flag == 0) {
            cout << "no" << endl;
            return 0;
        }

        // 若找到视频流,进行相关的操作
        currentByte += byte[j];
        currentClock += Time[j];
        num.push_back(j);
    }

    for(i = 0; i < n; i++) {
        cout << num[i] << " ";
    }

    return 0;
}


2. 搜索 + 回溯 + 剪枝

此题我们的思想类似于全排列,也就是将所有序号按字典序从小到大排列出来,当找到第一个满足条件的序列,就停止算法。

但由于 n < 10000,所以该算法会超时,但也算是提供了一种新思路。


算法思路

  1. 函数 f 用于搜索,参数有三个,一个是记录当前记录的视频个数 cur,一个是记录当前记录的视频的总字节数,一个是记录当前记录所消耗的总时钟周期。
  2. 递归终止条件为:记录的视频个数与 n 相等
  3. 每次 for 循环进行全排列时,条件不仅是没被记录过(v[i] == 0),还有 加上该视频,字节也在链路带宽限制范围内(sum + byte[i] <= r * (clock + Time[i]))

为什么要回溯呢?
因为我记录序号都共用一个 num 数组,在同一个循环内,如果你比如在索引为2时,想输出序号为3的情况,又想输出序号为4的情况,那就得想之前的给 “撤销” 了,再继续,同时标志数组也记得撤销哈



更多注释可查看下方的完整代码中,有助于理解。

代码如下

#include <iostream>
#include <vector>
#include <string.h>


using namespace std;

int byte[10001];
int Time[10001];
int n, r;
//int sum = 0; // 前面的视频流总值
vector<int> num; // 存各视频流编号,即 cur,要输出的
int v[10001]; // v[i] 用于标记数字是否被选中
int flag = 0; // 如果 flag 为1,说明找到序列了,停止算法

void f(int cur, int sum, int clock) {
    if(flag == 1)
        return;

    // 检查到最后一个看看满不满足调度了,如果还满足就不用递归了,直接输出并暂停算法
    if(cur == n + 1) {
        // 调度范围内
        for(int i = 0; i < num.size(); i++) {
            cout << num[i] << " ";
        }

        //cout << endl;
        flag = 1;
        return;
    }

    for(int i = 1; i <= n; i++) {
        if(!v[i]) {
            // 看看若加入当前编号的流,满不满足调度,如果还满足就继续递归了,否则直接剪枝
            //cout << "cur=" << cur << " sum=" << sum << " byte=" << byte[cur] << " Time=" << Time[cur] << " clock=" << clock << endl;
            if(sum + byte[i] <= r * (clock + Time[i])) {
                v[i] = 1;
                num.push_back(i);
                f(cur + 1, sum + byte[i], clock + Time[i]);
                num.pop_back();
                v[i] = 0;
            }
        }

    }
}

int main()
{
    memset(v, 0, sizeof(v));
    // 搜索+回溯+剪枝
    cin >> n >> r;

    for(int i = 1; i <= n; i++) {
        cin >> byte[i] >> Time[i];
    }

    f(1, 0, 0);

    // 如果执行完上面的算法,flag 还是0,即没有找到合适序列,那就输出 no
    if(flag == 0) {
        cout << "no" << endl;
    }

    return 0;
}

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

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

相关文章

lua-快速入门学习

lua-快速入门学习 安装 centos环境&#xff1a; yum install lua windows&#xff1a; window 下你可以使用一个叫 “SciTE” 的 IDE环 境来执行 lua 程序&#xff0c;下载地址为&#xff1a; Github 下载地址&#xff1a;https://github.com/rjpcomputing/luaforwindows/…

基于JavaSpringmvc+Vue+elementUI大学生求职招聘系统详细设计实现

博主介绍&#xff1a;✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取联系&#x1f345;精彩专栏推荐订阅&#x1f447;&#x1f…

前端开发技巧记录

1.取数组最后一位 let arr[1,2,3,4,5] console.log(arr[arr.length-1]) //5 console.log(arr.at(-1)) // 52.用??代替||&#xff0c;判空 ||运算符是左边是‘’ false 0 null undifined等&#xff0c;都会返回后侧的值。而??必须运算符左侧的值为null或undefined时&#x…

智能家居系统 QT

一 环境范围设置 &#xff08;1&#xff09;界面添加新控件 在mainwindow.ui 添加控件&#xff1a; 控件的类型 文本内容 对象名&#xff08;唯一&#xff09; 是否有槽函数 QLabel <温度< lable_随意 否 QLabel <湿度< lable_随意 否 QLabel <光…

CTF-misc练习(https://buuoj.cn)之第一页

一、金胖子 1.打开gif&#xff0c;看到有东西闪过&#xff0c;把gif分帧保存 2.就得到flag&#xff1a; 二、二维码 1.分析压缩包&#xff1a; 2.解压图片&#xff0c;分析图片&#xff0c;还有一个隐藏文件&#xff1a; 3.分离图片&#xff1a; 4.图片需要输入密码&#xff…

android studio 加载html文件(备忘)

android studio版本&#xff1a;2021.2.1 例程名称&#xff1a;htmlFile 我做的一个小东西需要一个软件协议之类的&#xff0c;之前直接用textview做&#xff0c;修改起来太麻烦&#xff0c;所以改成加载html文件&#xff0c;即解决了txt可能被修改的问题&#xff0c;如果下次…

python 3 - Clipspy模块使用

一、clipspy安装&#xff1a; Clipspy底层是基于clips规则引擎开发、支持python3的一个模块&#xff0c;在python3的工程中&#xff0c;可以通过调用clipsy的API接口实现clips规则引擎。 在线安装&#xff1a; pip install clipspy 当出现Successfully installed字样时&…

从零开始的深度学习之旅(3)

目录神经网络的损失函数1.损失函数的引入2.损失函数3.回归&#xff1a;误差平方和SSE3.1 MSE的使用3.2 二分类交叉熵损失函数3.3 极大似然估计推导二分类交叉熵损失3.4 用tensor实现二分类交叉熵损失4.多分类交叉熵损失函数4.1 实现多分类交叉熵损失神经网络的损失函数 1.损失…

Excel - 获取帮助信息,查找Sheet中和VBA里的可用函数

Excel获取帮助信息 在使用Excel时&#xff0c;可以点击菜单的Help&#xff0c;可以获取帮助信息或Training。 点击Help帮助信息&#xff1a; 如果你觉得查看不方便&#xff0c;开可以使用浏览器&#xff0c;访问官网线上支持文档&#xff1a; Excel help & learning 而点击…

【微服务】GateWay概念与使用

一、API 网关功能&#xff1a; 路由到指定位置&#xff1a;后台管理系统经常给各个服务发送请求&#xff0c;某一个服务掉线了&#xff0c;我们不可能手动去修改端口号&#xff0c;让它去其他机器找。因此&#xff0c;需要 API 网关&#xff0c;让其帮助我们将请求路由到正确位…

【华为OD机试真题 python】竖直四子棋【2022 Q4 | 200分】

■ 题目描述 【竖直四子棋】 竖直四子棋的棋盘是竖立起来的,双方轮流选择棋盘的一列下子,棋子因重力落到棋盘底部或者其他棋子之上,当一列的棋子放满时,无法再在这列上下子。 一方的4个棋子横、竖或者斜方向连成一线时获胜。 现给定一个棋盘和红蓝对弈双方的下子步骤,…

学会问问题

推荐文档&#xff1a;学会问问题&#xff1b; 目录 三句话原则 你就是孙子 问问题过程 第一步—学会问好 示例如下 第二步—有屁快放 问问题需要加上的前缀或者后缀&#xff1a; 示例如下 第三步—介绍自己的框架 示例如下 第四步—介绍自己的解决思路 示例如下 …

spring cache (Redis方式)

目录前置pom: jar配置文件: application.ymlMyCacheConfig.java效果图前置 会演示springcache的使用方式 项目地址: https://gitee.com/xmaxm/test-code/blob/master/chaim-cache/chaim-spring-cache/chaim-spring-cache-redis/README.md 前置配置 本篇文章是基于上篇文章进行…

Flutter 使用FFI+CustomPainter实现全平台渲染视频

Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FFICustomPainter渲染视频&#xff08;本章&#xff09; 文章目录Flutter视频渲染系列前言一、如何实现1、C/C实现视频采集&#xf…

3. 使用PyTorch深度学习库训练第一个卷积神经网络CNN

这篇博客将介绍如何使用PyTorch深度学习库训练第一个卷积神经网络&#xff08;CNN&#xff09;。训练CNN使用 KMNIST 数据集&#xff08;MNIST digits数据集的替代品&#xff0c;内置在PyTorch中&#xff09;识别手写平假名字符&#xff08;handwritten Hiragana characters&am…

图的二种遍历-广度优先遍历和深度优先遍历

图的广度优先遍历 1.树的广度优先遍历 这样一个图中&#xff0c;是如何实现广度优先遍历的呢&#xff0c;首先&#xff0c;从1遍历完成之后&#xff0c;在去遍历2,3,4&#xff0c;最后遍历5 &#xff0c;6 , 7 , 8。这也就是为什么叫做广度优先遍历&#xff0c;是一层一层的往…

36个数据分析方法与模型

目录一、战略与组织二、质量与生产三、营销服务四、财务管理五、人力资源六、互联网运营好的数据分析师不仅熟练地掌握了分析工具&#xff0c;还掌握了大量的数据分析方法和模型。这样得出的结论不仅具备条理性和逻辑性&#xff0c;而且还更具备结构化和体系化&#xff0c;并保…

Python连接MYSQL、SQL Server、Oracle数据入库一网打尽

描述&#xff1a; Python众所周知用来数据提取&#xff0c;通俗说用来抓数据&#xff0c;将拿到的数据进行数据清洗、加工,分析等等。而其中最重要的部分就是数据爬取、数据入库这两部分了&#xff0c;至于数据分析那就特别考察你的SQL能力&#xff0c;如果是自己设计页面&…

马齿苋多糖偶联顺铂复合物/黄连素偶联顺铂化合物/载顺铂mPEg-PGA纳米微球制备方法

小编今天整理了马齿苋多糖偶联顺铂复合物/黄连素偶联顺铂化合物/载顺铂mPEg-PGA纳米微球制备方法&#xff0c;一起来看&#xff01; 黄连素偶联顺铂化合物制备方法: 以A549/DDP细胞为研究对象,分别加入12 μg/mL的顺铂,浓度为20 μmol/L,40 μmol/L,80 μmol/L的黄连素12 μg/…

艾美捷EndoGrade卵清蛋白重组示例说明

卵清蛋白是一种优质蛋白质&#xff0c;占蛋清蛋白总量的 54%-69%&#xff0c;卵清蛋白是典型的球蛋白&#xff0c;分子量为 44.5k Da&#xff0c;属含磷糖蛋白&#xff0c;含有四个自由巯基、385 个氨基酸残基。这些氨基酸残基相互缠绕折叠形成具有高度二级结构的球型结构&…