第一题:有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?

采用了两个矩阵mx,mn

mx[i][j]是从i个选出j个,并以i为结束,满足相邻位置不大于j的最大乘积

mn[i][j]是从i个选出j个,并以i为结束,满足相邻

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 110
const long long INF=1e8;
long long a[N],mx[N][N],mn[N][N];//事先声明了数组,因为最后数可能会很大,所以定义的longlong类型
long long max(long long a,long long b)
    {
    return a>b?a:b;
}
long long min(long long a,long long b)
    {
    return a>b?b:a;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)//这种输入数组的方法
        scanf("%lld",&a[i]);
    int k,d;
    scanf("%d%d",&k,&d);

    for(int i=1;i<=n;i++)//初始化mx,mn数组
    {
        mx[i][0]=1;
        mn[i][0]=1;
        for(int j=1;j<=k;j++)
            {
            mx[i][j]=-INF;
            mn[i][j]=INF;
        }
    }
    long long mmx=-100,mnx=100;//mmx主要是用于当k=1时选出数组中最大的元素
    long long ans=-INF;
    for(int i=1;i<=n;i++)
    {
        mmx=max(mmx,a[i]);
        mx[i][1]=a[i];
        mn[i][1]=a[i];
        if(k==1)
            ans=max(ans,mmx);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=2;j<=k;j++)//j=1已经讨论过了
        {
            for(int r=i-1;r>=max(1,i-d)&&r>=j-1;r--)//mx[r][j-1]表示从前r个中选出j-1个最大的乘积,所以r>=j-1;r只能最多回溯d个或者回溯到底
             {
                mx[i][j]=max(mx[i][j],mx[r][j-1]*a[i]);
                mx[i][j]=max(mx[i][j],mn[r][j-1]*a[i]);
                mn[i][j]=min(mn[i][j],mx[r][j-1]*a[i]);
                mn[i][j]=min(mn[i][j],mn[r][j-1]*a[i]);
                if(j==k) ans=max(ans,mx[i][j]);
            }
        }
    }
    cout<<ans;
}

位置不大于j的最小乘积

时间: 2024-08-05 11:26:51

第一题:有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?的相关文章

二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置

看到一个非递归交换一个二叉树的左右孩子的位置,于是想实现之,才发现非递归的先中后序遍历都忘记了……于是杂七杂八的写了一些,抄抄资料就实现了,然后实现非递归交换两个孩子的位置还是相当容易的.先直接上代码吧,其实这东西还是得自己写写过一遍的,印象才会更加深刻: #include <iostream> #include <fstream> #include <string> #include <stack> using std::cout; using std::

poj 1743 Musical Theme(男人八题&amp;后缀数组第一题)

Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 17298   Accepted: 5939 Description A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the range 1..88, each representing a key on the

下午第一题

2017上半年 阅读下列说明和图,回答问题1至问题4,将解答填入答题纸的对应栏内. [说明] 某医疗器械公司作为复杂医疗产品的集成商,必须保持高质量部件的及时供应.为了实现这一目标,该公司欲开发一采购系统.系统的主要功能如下: 1.检查库存水平.采购部门每天检查部件库存量,当特定部件的库存量降至其订货点时,返回低存量部件及库存量. 2.下达采购订单.采购部门针对低存量部件及库存量提交采购请求,向其供应商(通过供应商文件访问供应商数据)下达采购订单,并存储于采购订单文件中. 3. 交运部件.当供应

区赛第一题讲解+基础算法——桶排序与快速排序

截止到上篇随笔,我们已经学完了c++中所有的基础语句,这意味着,noip普及组的第一题你已经可以拿满分了.为了纪念这个伟大的时刻,今天要上的这道题,是刚刚考完的海淀区区赛第一题. 题目描述: 已知RFdragon有n个杯子,每个杯子的容积都是无限大,里面都装有1L水.由于RFdragon的杯子实在太多了,他决定扔掉一些杯子,使剩下的杯子不超过k个.RFdragon每次可以把两个装水体积相同的杯子中的水倒在其中一个杯子里,然后扔掉另一个杯子.有时候,RFdragon无论如何也不能使剩下的杯子不超过

leetcode中第一题twosum问题解答算法的可行性证明

leetcode中第一题twosum问题解答算法的可行性证明 一.引入 关于leetcode中第一题twosum问题,网上已有不少高人做出过解答,并提出了切实可行的算法实现.我在解答该题时参考了博客http://www.zixue7.com/article-9576-1.html的解答.为让读者更直观地阅读和理解本文,先简要摘录以上博客的内容如下: 题目还原 Two Sum Given an array of integers, find two numbers such that they a

LeetCode 第一题,Two Sum

今天早上起来去机房的路上还在想,一直不做算法题老是觉得不踏实.做做题总是让自己觉得自己真的在做做学习.... 这也算是一种强迫症吧. 那就从今天开始做做LeetCode,因为好久没做过了,所以第一题还是看了别人的题解和思路,算是找找感觉. 总的来说第一题是个水.... 题目还原 Two Sum Given an array of integers, find two numbers such that they add up to a specific target number. The fu

“金山杯2007逆向分析挑战赛”第一阶段第一题分析

题目来自于如下网址: http://www.pediy.com/kssd/ 第13篇 论坛活动 \ 金山杯2007逆向分析挑战赛 \ 第一阶段 \ 第一题 \ 题目 \ [第一阶段 第一题]: 现将此题目概述粘贴如下: CrackMe.exe 是一个简单的注册程序,见附件,请写一个注册机: 要求: 1. 注册机是KeyGen,不是内存注册机或文件Patch 2. 注册机可以使用ASM,VC,BC,VB,Delphi等语言书写,其他谢绝使用. 3. 注册机必须可以运行在Windows系统上. ..

看雪CTF2016CrackMe攻防大赛——第一题

前言 暑假来了,不知道做些什么好,就拿看雪CTF的题来练习练习,学习下大佬们的操作.这是2016年CrackMe攻防赛的第一题,我就被难到了.本来都已经放弃了,但是幸得大佬分享,故跟随大佬的步伐粗略分析了下. 准备 系统:Windows 7 x64 ultimate 工具:IDA pro v7.0(最好用7.0,用6.8会有些问题) 分析 首先运行Crack_Me. 有一个密码输入框,一个OK按钮和一个计数框. 随便输入密码,获得失败提示,提示失败. 载入OD,先运行一下,可是却发现程序直接终止

leetcode中的两数之和(第一题:简单)

描述:给定一个整数数组和一个目标值,找出数组中和为目标值的 两个 数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用.示例:给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 题意:给一个整形的数,这个数在会在给定数组的两个位置数相加的和!这个和是指值的相加,不是数组的索引相加:如果在数组中有这样的两个数,要求返回两个数的索引(也就是数组的下标): 解法一:暴力方法:应用