算法与数据结构实验题 4.2 小 F 打怪
★实验任务
小 F 很爱打怪,今天因为系统 bug,他提前得知了 n 只怪的出现顺序以及击 倒每只怪得到的成就值 ai。设第一只怪出现的时间为第 1 秒,这个游戏每过 1 秒 钟出现一只新怪且没被击倒的旧怪消失。小 F 决定发动一次技能,他的技能最多 维持 k 秒,他希望获得最大的成就值,请你帮他计算他发动技能的时间 l 和技能 结束时间 r(r-l+1<=k)。当存在多种方案使得成就值最大时,选择技能发动时间 l 最小的方案,再选择技能持续时间 r-l+1 最小的方案。
★数据输入
输入第一行为两个正整数 n(1<=n<=100000),k(0<k<=n),表示出现 n 只怪, 小 F 的技能最多维持 k 秒。 输入第二行为 n 个整数,表示小 F 击倒第 i 秒钟出现的怪能给有获得的成就 值 ai(-1000<=a[i]<=1000)。
★数据输出
输出为一行三个数。第一个数为可获得的最大成就值,第二个数为技能发动 时间 l,第三个数为技能结束时间 r。
| 输入示例 | 输出示例 |
|---|---|
| 6 3 -1 2 -6 5 -5 6 |
6 4 6 |
| 输入示例 | 输出示例 |
|---|---|
| 5 5 -1 -1 -1 -1 -1 |
-1 1 1 |
★思路
这道题的目标就是找到长度不超过k的最大子序列和,求子序列和可以使用前缀和与后缀和的思想。如果先使用前缀和做法,把数组倒序就是后缀和做法。
前缀和的概念就是第i个数前面所有数字的和。所以[l,r]区间的和可以写成。(sum[r]-sum[l])。

这样子要找到数字i前面不超过k长度的最大子序列和,就要找到它前面k个前缀和的最小值。(因为sum[i]为定值)。
要找到sum[i]前面k个前缀和的最小值做法是,用递增队列。
建立结构体数组来模拟这个过程。
struct intt
{
int value;
int pos; //记录位置,判断长度是否超过k
int start;
};
首先队首元素存0(因为sum[1]前面没以有元素,所以sum[0]=0)。
接下来对于每一个sum[i],先用它去减队首元素(队首元素代表第i个数前面的最小前缀和)。然后把它加入队列。
如果它比它前面的数字值小,就把它前面的元素弹出(这相当于更新当前的最小值)。
如果它比它前面的数字大,就把它留起来备用。因为他前面的数字最多可以使用k次,如果他前面元素使用k次被弹出后,就要用它来补充当前最小前缀和这个位置了。
如果它与前面元素相等的话,也要弹出前面元素,因为前面元素已经被使用它过一次了,而它没有被使用过。
这样子我们找到的是每个数字i所对应的起始位置比较靠后的满足条件的最大子区间和。如果我们把数组倒序进行这个操作那么我们就找到了满足题目要求的“当存在多种方案使得成就值最大时,选择技能发动时间 l 最小的方案,再选择技能持续时间 r-l+1 最小的方案”。
★Code
#include<iostream>
#include<string.h>
using namespace std;
struct intt
{
int value;
int pos;
int start;
};
int a[100005]; //普通的数组
intt dp[100005]; //模拟队列,队首元素代表最小前缀和
intt sum[100005]; //前缀和数组
intt mmax[100005]; //以i结尾符合条件的区间最大和
int main()
{
int n, k, i;
intt *head = &dp[0];
intt *tail = &dp[0];
scanf("%d %d",&n,&k);//cin >> n >> k;
memset(a, 0, sizeof(a));
memset(dp, 0, sizeof(dp));
memset(sum, 0, sizeof(sum));
memset(mmax, 0, sizeof(mmax));
for (i = n; i >= 1; i--)
{
scanf("%d",&a[i]);// cin >> a[i];
}
for (i = 1; i <= n; i++)
{
sum[i].value = sum[i - 1].value + a[i];
sum[i].pos = i;
}
for (i = 1; i <= n; i++)
{
if (tail->pos - head->pos >= k)
head++;
mmax[i].value = sum[i].value - head->value;
mmax[i].start = head->pos;
// cout<<mmax[i].start<<endl;
while (1)
{
if (sum[i].value>tail->value)
{
tail++;
tail->value = sum[i].value;
tail->pos = i;
break;
}
else if (sum[i].value == tail->value)
{
tail->pos = i;
break;
}
else
{
if (tail == head)
{
tail->value = sum[i].value;
tail->pos = sum[i].pos;
break;
}
else
{
tail->value = 0;
tail->pos = 0;
tail--;
}
}
}
}
/*for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
for(int i=1;i<=n;i++)
{
cout<<mmax[i].value<<" ";
}
cout<<endl;*/
int maxx = mmax[1].value;
for (i = 1; i <= n; i++)
{
if (mmax[i].value>maxx)
maxx = mmax[i].value;
}
int temp;
for (i = n; i >= 1; i--)
{
if (mmax[i].value == maxx)
{
temp = i;
break;
}
}
int flag = temp;
int tempp = maxx;
while (1)
{
tempp -= a[flag];
if (!tempp)
break;
flag--;
}
printf("%d %d %d", maxx, n + 1 - temp, n + 1 - flag);
//cout << maxx << " " << n + 1 - temp << " " << n + 1 - flag;
return 0;
}
算法与数据结构实验题 4.2 小 F 打怪的更多相关文章
- 算法与数据结构实验题 6.4 Summary
★实验任务 可怜的 Bibi 丢了好几台手机以后,看谁都像是小偷,他已经在小本本上记 下了他认为的各个地点的小偷数量. 现在我们将 Bibi 的家附近的地形抽象成一棵有根树.每个地点都是树上的 一个节 ...
- 算法与数据结构实验题 4.1 伊姐姐数字 game
★实验任务 伊姐姐热衷于各类数字游戏,24 点.2048.数独等轻轻松松毫无压力.一 日,可爱的小姐姐邀请伊姐姐一起玩一种简单的数字 game,游戏规则如下: 一开始桌上放着 n 张数字卡片,从左到右 ...
- 算法与数据结构实验题 6.3 search
★实验任务 可怜的 Bibi 刚刚回到家,就发现自己的手机丢了,现在他决定回头去搜索 自己的手机. 现在我们假设 Bibi 的家位于一棵二叉树的根部.在 Bibi 的心中,每个节点 都有一个权值 x, ...
- 算法与数据结构实验题6.4 order (二叉树)
1.题目: 2.代码: #include<iostream> #include<algorithm> using namespace std; struct Node { in ...
- 算法与数据结构实验题 5.2 Missile
1.题目: 2.解题思路: 把每个点对应的两条半径求出,之后对d1进行升序排序,对应d2也改变位置.其中一个圆心的半径r1确定之后,除去第一个圆包围的点,在其余点中找到另外一个圆的最长的半径r2,此时 ...
- HDU 3791 二叉搜索树 (数据结构与算法实验题 10.2 小明) BST
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3791 中文题不说题意. 建立完二叉搜索树后进行前序遍历或者后序遍历判断是否一样就可以了. 跟这次的作业第 ...
- 数据结构_sfdg(小F打怪)
问题描述 小 F 很爱打怪, 今天因为系统 bug, 他提前得知了 n 只怪的出现顺序以及击倒每只怪得到的成就值 ai. 设第一只怪出现的时间为第 1 秒,这个游戏每过 1 秒钟出现一只新怪且没被击倒 ...
- 基础算法和数据结构高频题 II
DFS的两种理解方式:1. 按照实际执行顺序模拟 (适合枚举型DFS,下节课内容)2. 按照DFS的定义宏观理解 (适合分治型DFS,本节课内容) 1 Convert BST to Greater T ...
- 第三章 基础算法和数据结构高频题 I
区间类问题 1 Missing Interval public List<String> findMissingRanges(int[] nums, int lower, int uppe ...
随机推荐
- mint-ui message box 问题;
当引用 mint-ui message box 的 出现的问题,我暂时是不知道为什么: 官网是这样写的: 于是 我也这么做的:(这里用小写,具体我也不清楚,毕竟文档上写的也不是很清楚,但是只有这样写, ...
- Redis(八):Redis的复制(Master/Slave)
Redis的复制(Master/Slave)目录导航: 是什么 能干嘛 怎么玩 复制原理 哨兵模式(sentinel) 复制的缺点 是什么 官网 行话:也就是我们所说的主从复制,主机数据更新后根据配置 ...
- PHP基础1--环境搭建
主要: 环境搭建 站点配置 环境搭建 web运行流程: 1. 浏览器输入地址,回车(发送请求) 2. 根据规则找到对应web服务器.规则如下: 首先在本机hosts文件中找对应IP hosts位置: ...
- 大数据学习--day06(Eclipse、数组)
Eclipse.数组 Eclipse 的基本设置 调节控制条字体大小. Window -> Preferences -> General -> Appearance -> ...
- HBase学习(一):认识HBase
一.大数据发展背景 现今是数据飞速膨胀的大数据时代,大数据强调3V特征,即Volume(量级).Varity(种类)和Velocity(速度). ·Volume(量级):TB到ZB. ·Varity( ...
- c语言程序设计:用strcpy比较数组(银行卡密码程序设计),strcpy(复制数组内容)和getchar()(敲键盘字符,统计不想要的字符的个数)
统计从键盘输入一行字符的个数: 1 //用了getchar() 语句 2 //这里的\n表示回车 #include <stdio.h> #include <stdlib.h> ...
- java-执行流程控制语句
就像有知觉的生物一样,程序必须在执行的过程中控制它的世界,并做出选择.java使用执行流程控制语句做出选择. 1.选择语句 if if(布尔表达式){ 业务逻辑1; }else{ 业务逻辑2: } s ...
- Java设计模式(21)——行为模式之备忘录模式(Memento)
一.概述 概念 UML简图 角色 根据下图得到角色 备忘录角色(Memento).发起人角色(Originator).负责人角色(Caretaker) 二.实践 使用白箱实现,给出角色的代码: 发起人 ...
- 北京Uber优步司机奖励政策(12月17日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 北京Uber优步司机奖励政策(9月14日~9月20日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...