题解:2018级算法第三次上机 C3-Zexal的浩瀚星辰
题目描述:
样例:
实现解释:
一道结合了火箭发射的贪心题目
知识点:
贪心,优先队列
题目分析:
根据题目描述可知,延迟后时间是正常推进的,也就是假设共有n个火箭,推迟k小时。则在到达k+1小时时,每过一个小时只要火箭没发射完都会有k(如果k大于n就是有剩余数量)个火箭会遭受延迟的损失,显然这是必然的(因为到达k小时前的损失都已经确定了,无法改变)。
那么依据题意只要使得每次这k个火箭的损失最小即可,而如何最小:让其中单位时间损失最大的火箭发射即可,这样一定比发射其他火箭的损失要小。
于是便可得出贪心的状态转移方程:
cost[i] = cost[i-1]+sum(sum既是此时除去最大损失火箭的总损失量)
sum的获取可以利用排序实现,不过考虑到时间问题,还是用优先队列进行最好,边输入边处理便可解决,具体实现可参考完整代码,内含注释。
难点:
即如何获得当前状态的sum,常规来说只需去除损失最大的火箭然后遍历剩余的相加即可。一次优化:利用sum数组和out变量提前存储避免遍历,不过还是需要排序;二次优化:利用优先队列获取最大值,免去排序。
完整代码:
优先队列版(过了):
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
//考虑到数据范围,这里需要用long long进行储存
//表面上看起来没有超范围,但是延迟时间是需要相乘的,因此还是会超过
priority_queue<long long> pq;
long long sum[];
long long cost[];
int main()
{
ios::sync_with_stdio(false);
int n,k,temp;
long long p;//中间值记录每个火箭的损失
long long out;//统计发射出去火箭的损失和
while(cin >> n >> k)
{
memset(cost,,(n+k+)*sizeof(long long));
//按需初始化,减少时间消耗
sum[] = ;//sum需要用到前一个值,此处设0
out = ;
for(int i = ;i<=k+n;i++)
{
if(i <= n)
{
cin >> p;
sum[i] = sum[i-]+p;
pq.push(p);
}
//错误判断1:if(i <= k) if(i <= n) cost[k]+=(k-i+1)*p;
//这种情况第二个else会被编译器认为是i <= n的补集,会出错 //错误判断2:if(i <= k&&i <= n) cost[k]+=(k-i+1)*p;
//这种情况会导致i > k但i <= n的情况计算被忽略
//即延迟时间小于最后一个发射时间时 if(i <= k)//还没到延迟时间时依据p计算延迟时间时这个火箭的损失
{
if(i <= n) cost[k]+=(k-i+)*p;
//注意火箭只有n个,所以需要判断下
}
else//此时说明延迟已过,需要发射火箭
{
temp = i>n?n:i;
//当i>n则应该temp=n以保证每次获取到的为损失的总和
//这样减去已经发射火箭的损失和就是这次发射的总损失
out += pq.top();//选择单位损失最高的火箭发射
pq.pop();
cost[i] = cost[i-] + sum[temp] - out;
//i小时的损失等于i-1小时损失加上这一小时的新损失
//当前时间本应发射的总损失减去已经发射的总损失即是延迟火箭新产生的总损失 //out去除形式,本质相同,只是直接在sum处去除(影响也可保留)
//不过没有out好理解
// temp = i>n?n:i;
// sum[temp] -= pq.top();
// pq.pop();
// cost[i] = cost[i-1] + sum[temp];
}
}
cout << cost[k+n] << '\n';
//延迟时间和总发射时间之和即是所有火箭发射完全的时间
}
return ;
}
数组排序版(TLE):
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
long long p[];
long long sum[];
//long long cost[1000010];
int main()
{
ios::sync_with_stdio(false);
int n,k;
int temp;
long long out;
while(cin >> n >> k)
{
long long cost[n+k+];
memset(cost,,sizeof(cost));
sum[] = ;
for(int i = ;i<=n;i++)
{
cin >> p[i];
sum[i] = sum[i-]+p[i];
if(i <= k) cost[k]+=(k-i+)*p[i];
}
out = ;
for(int i = ;i<=n;i++)
{
temp = k+i;
if(temp > n) temp = n;
sort(p+,p+temp+);
out += p[temp];
p[temp] = ;
cost[k+i] = cost[k+i-] + sum[temp] - out;
//此时out不能省略了,因为sum已经确定了
}
cout << cost[k+n] << '\n';
}
return ;
}
题解:2018级算法第三次上机 C3-Zexal的浩瀚星辰的更多相关文章
- 题解:2018级算法第五次上机 C5-图2
题目描述: 样例: 实现解释: 所有结点对最短路径的板子题 知识点: 寻找所有结点对最短路径,动态规划 坑点: 无坑,注意建边即可 使用的算法为floyd算法 按照程序顺序解释如下: 首先建图,以邻接 ...
- 题解:2018级算法第四次上机 C4-最小乘法
题目描述: 样例: 实现解释: 和字符串处理结合的动态规划,个人认为比较难分析出状态转移方程,虽然懂了之后挺好理解的 知识点: 动态规划,字符串转数字 题目分析: 首先按照最基础:依据题意设计原始dp ...
- 题解:2018级算法第六次上机 C6-不Nan的过河
题目描述: 样例: 实现解释: 一道因为没排序做了一个小时没做出来的二分答案模板题(手动呲牙) 知识点: 二分答案,最大值最小化 坑点: 排序,judge(mid)函数内计数的实现 其实从最长一步的最 ...
- 题解:2018级算法第六次上机 C6-危机合约
题目描述 样例: 实现解释: 没想到你也是个刀客塔之二维DP 知识点: 动态规划,多条流水线调度?可以看做一种流水线调度 坑点: 输入内容的调整(*的特殊判定),开头结尾的调整策略 从题意可知,要做的 ...
- 题解:2018级算法第四次上机 C4-商人卖鱼
题目描述: 样例: 实现解释: 需要简单分析的贪心题 知识点: 贪心,自定义排序,提前存储 题目分析: 卖鱼,鱼卖出去需要时间,鱼没被卖出去之前需要吃饲料 则有,如果卖a鱼的话b鱼会吃饲料c份,而卖b ...
- 2016级算法第三次上机-G.Winter is coming
904 Winter is coming 思路 难题.首先简化问题, \(n\) 个0与 \(m\) 个1排成一列,连续的0不能超过x个,连续的1不能超过y个,求排列方法数. 显然会想到这是动态规划. ...
- 2016级算法第三次上机-C.AlvinZH的奇幻猜想——三次方
905 AlvinZH的奇幻猜想--三次方 思路 中等题.题意简单,题目说得简单,把一个数分成多个立方数的和,问最小立方数个数. 脑子转得快的马上想到贪心,从最近的三次方数往下减,反正有1^3在最后撑 ...
- 2016级算法第三次上机-B.Bamboo和巧克力工厂
B Bamboo和巧克力工厂 分析 三条流水线的问题,依然是动态规划,但是涉及的切换种类比较多.比较易于拓展到n条流水线的方式是三层循环,外层是第k个机器手,里面两层代表可切换的流水线 核心dp语句: ...
- 2016级算法第三次上机-F.ModricWang的导弹防御系统
936 ModricWang的导弹防御系统 思路 题意即为:给出一个长度为n的序列,求出其最长不降子序列. 考虑比较平凡的DP做法: 令\(nums[i]\) 表示这个序列,\(f[x]\) 表示以第 ...
随机推荐
- [每日一题2020.06.14]leetcode #70 爬楼梯 斐波那契数列 记忆化搜索 递推通项公式
题目链接 题意 : 求斐波那契数列第n项 很简单一道题, 写它是因为想水一篇博客 勾起了我的回忆 首先, 求斐波那契数列, 一定 不 要 用 递归 ! 依稀记得当年校赛, 我在第一题交了20发超时, ...
- 2019-01-31 Python学习之BFS与DFS实现爬取邮箱
今天学习了python网络爬虫的简单知识 首先是一个爬取百度的按行读取和一次性爬取 逐行爬取 for line in urllib.request.urlopen("http://www.b ...
- Anaconda 安装tensorflow出现错误
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorflow\python\framework\dtypes.py: ...
- Redis系列(五):数据结构List双向链表中基本操作操作命令和源码解析
1.介绍 List是通过ListNode实现的双向链表. 1.双端:获取某个结点的前驱和后继结点都是O(1) 2.无环:表头的prev指针和表尾的next指针都指向NULL,对链表的访问都是以NULL ...
- vue入门的第一天: v-on使用
v-on的使用 简介: v-on 是一个事件绑定机制,可以缩写为@ 如: <input type="button" value="按钮" v-on:cli ...
- 线程间配合:Condition、Semaphore、CountDownLatch、CyclicBarrier
1 重入锁的好搭档:Condition条件 如果大家理解了Object.wait()和Object.notify()方法的话,那么就能很容易理解Condition接口了.它和wait()和notify ...
- elasticSearch中集群状态的guan'l
es中集群出现上面的问题一般是磁盘空间不够引起的,就是node节点所在的磁盘空间不足引起的 es整个集群放在c盘,都快满了 说明es的磁盘已经快被使用完了,我们可以临时更新下磁盘空间大小 修改 ES分 ...
- JavaWeb网上图书商城完整项目--day02-7.提交注册表单功能之流程分析
1.点击注册之后将提交的信息传递到UserServlet的public String regist方法进行处理,然后将东西通过service进行处理 业务流程:
- ES7.x客户端的认证创建一步一步来
前言 好久没来写博客了,还是简单的记录一下吧.今天要写的是es在7.x版本后的客户端的创建以及一些es的查询所语句到的小问题.直接先吧客户端端的代码呈上. 正文 public class ESClie ...
- 深入理解JVM(③)虚拟机的类加载过程
前言 上一篇我们介绍到一个类的生命周期大概分7个阶段:加载.验证.准备.解析.初始化.使用.卸载.并且也介绍了类的加载时机,下面我们将介绍一下虚拟机中类的加载的全过程.主要是类生命周期的,加载.验证. ...