这题在编程达人面前应该算是水题,但这算是我第一个做出来的动态规划程序,作为纪念,分享一下。题目链接:

https://www.nowcoder.com/practice/661c49118ca241909add3a11c96408c8?tpId=85&tqId=29830&tPage=1&rp=1&ru=/ta/2017test&qru=/ta/2017test/question-ranking

简单描述一下题目:有n个学生站成一排,每个学生有一个能力值,需要按顺序选取k名学生,使得k个学生的能力值乘积最大,求该最大值。这里有两个注意点:1、相邻的两名学生在排列中的编号不能超过d(d由题目输入给出);2、学生能力值可以为负。

一开始我大概知道是个动态规划程序,但确实不知道怎么设计,又看到数据规模很小,并且于是想用暴力法解决,然后就自然而然地超时了。先简单说一下暴力法,就是对每个合唱团的学生,有选它,或不选它两个选项。于是就可以枚举,枚举时需要记录这次访问的人index,已经选择的人数nowK,上一个选的人last(两者差<d时才能走“不选它”的选项),和当前乘积mul。程序结构比较简单,代码如下:

#include <iostream>
using namespace std;int n, k, d, a[50];
long long ans = -50ll * 50 * 50 * 50 * 50 * 50 * 50 * 50 * 50 * 50;
void DFS(int index, int nowK, int last, long long mul)
{if (nowK == k) {if (mul > ans)ans = mul;return;}if (index == n)return;if (last == -1 || index - last < d)DFS(index + 1, nowK, last, mul);DFS(index + 1, nowK + 1, index, mul*a[index]);
}int main()
{cin >> n;for (int i = 0; i != n; ++i)cin >> a[i];cin >> k >> d;DFS(0, 0, -1, 1);cout << ans << endl;return 0;
}

题目数据确实很小。这样的程序也能过80%。。。接下来说下动态规划的解法。

动态规划的核心是设计拥有无后效性的状态和状态转移方程,状态一般与“前i个”,“以第i个结尾”等有关。对于本题,先不考虑学生能力值为负的情况,可以把状态设置为“选择的学生数为i,最后一个选择的学生编号为j”的情况下的最大乘积,把状态存在一个数组里,这个状态就可以记为dp[i][j]。我们可以发现dp[i][j]的值只跟数组dp[i-1]中的各个项有关——在最后一个人编号是j的情况下,倒数第二个人的编号只能是j-d到j-1。因此,求dp[i-1][j-d] ~ dp[i-1][j-1]的最大值,再乘以a[j],就能够得到dp[i][j]。其中,dp[i-1]的各个项是由之前递推而来的(从0开始向上递推),于是我们可以直接使用结果而不必进行重复计算。

现在需要考虑学生能力值为负了,由于负负得正,所以不仅需要保存当前状态下的最大值,还要保存最小值,这样碰到负值,拿最小值乘才能得到真正的最大值。所以dp数组应该改为两个数组dmax,dmin。

最后一个问题是边界问题,递推总是要有边界的。由于是求乘积,所以在边界状态“选0个数”的情况下,不管最后一个选择的编号是几,数组都应当存1。还有,对于任意的i(选取学生的个数),显然j(最后一个学生的编号)必须至少为i,否则是不合常理的。

最后求数组dp[k]的项的最大值即可(dmax[k][i]代表“选取k个学生,最后一个学生是i”,应从dp[k][k]枚举)。下面给出程序代码,需要注意的是,这里学生的编号是1~n,与暴力解法的代码是不同的(学生编号0~n-1)。另外,其实还有使用滚动数组来减小空间复杂度的做法,这里就不赘述了。

#include <iostream>
#include <algorithm>
using namespace std;int n, k, d, a[50];
long long dmax[11][51], dmin[11][51];int main()
{// 初始化边界fill(dmax[0], dmax[1], 1);fill(dmin[0], dmin[1], 1);cin >> n;for (int i = 1; i <= n; ++i)cin >> a[i];cin >> k >> d;for (int i = 1; i <= k; ++i)for (int j = i; j <= n; ++j) { //  在选取i个人的情况下,j至少为iint s = max(i - 1, j - d);  //  同理s虽然从j - d开始枚举,但至少应为i - 1long long cmin = dmin[i - 1][s], cmax = dmax[i - 1][s];for (; s < j; ++s) {cmax = max(cmax, dmax[i - 1][s]);cmin = min(cmin, dmin[i - 1][s]);}//  状态转移方程if (a[j] < 0) {dmax[i][j] = cmin*a[j];dmin[i][j] = cmax*a[j];}else {dmax[i][j] = cmax*a[j];dmin[i][j] = cmin*a[j];}}// 遍历所有的最大值,其中的最大值即为最终答案long long ans = dmax[k][k];for (int i = k + 1; i <= n; ++i)ans = max(ans, dmax[k][i]);cout << ans << endl;return 0;
}

牛客网编程题——合唱团(网易2017)相关推荐

  1. Python 牛客网编程题输入用例问题

    Python 牛客网编程题的输入用例 前言 切入正题 输入字符串 输入整数 输入列表 后记 前言 在牛客网刷题的时候,发现明明在python本地编译器能够轻松解决的输入用例问题,到牛客网在线编译就得好 ...

  2. 牛客网编程题python_牛客网数据结构练习题

    第一次使用牛客做编程题,刚开始不了解如何输入输出,查了查才知道.我用的是语言是 Javascript v8 6.0.0 readline() 表示得到输入的字符串,如果是多行的话,每readline一 ...

  3. python牛客网编程题_一波优秀的自学编程语言网站

    网课已经开设两三个月了 同学们上网课的效果怎么样呢? 特别是学编程的同学 没有了学校的学习氛围 没有了老师面对面教学指导 你是否为了编程而焦头烂额,生无可恋呢? 没事,现在同学们的福利来啦! 下面是给 ...

  4. python牛客网编程题_【面经】小米软件开发一面(python)面经 2020 2020

    作者:JessyTsui https://www.nowcoder.com/discuss/580721?type=2&order=0&pos=15&page=1&ch ...

  5. 牛客网—编程题(1)牛牛的礼物

    题目描述 众所周知,牛妹有很多很多粉丝,粉丝送了很多很多礼物给牛妹,牛妹的礼物摆满了地板.地板是N\times MN×M的格子,每个格子有且只有一个礼物,牛妹已知每个礼物的体积.地板的坐标是左上角(1 ...

  6. 牛客网编程题python输入输出_牛客网算法题目记录

    车站建设问题 有10^8个村庄排在一条公路上,依次编号为0~10^8-1,相邻村庄距离为1,其中有n个村庄居住着牛牛,居住着牛牛的村庄从小到大依次为a0~an-1,其中保证a0=0. 现在需要建设车站 ...

  7. 牛客网 [编程题]数字和为sum的方法数

    题目描述: 给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数. 当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案. 输入描述: 输入为两行:第一行 ...

  8. 牛客网 [编程题]餐馆

    题目描述: 某餐馆有n张桌子,每张桌子有一个参数:a 可容纳的最大人数: 有m批客人,每批客人有两个参数:b人数,c预计消费金额. 在不允许拼桌的情况下,请实现一个算法选择其中一部分客人,使得总预计消 ...

  9. 牛客网编程题07--提取不重复的整数

    题目 代码: // ExtractNum.cpp : 定义控制台应用程序的入口点. // 从右到左 提取一个不重复的整数 // 提取,string转int,int转string#include &qu ...

最新文章

  1. 写给笨蛋徒弟的学习手册(1)——完整C#项目中各个文件含义
  2. axios02-其他使用方式(推荐)
  3. 2018-12-25 上机作业
  4. python工程师干什么的_大数据开发工程师薪资待遇及招聘要求?
  5. 读书笔记_中国期货市场量化交易(李尉)01
  6. 双标准线等角圆锥投影转换_青学堂--花花的地理课堂之地图投影知多少
  7. 摄像头NV21格式转RGB的JAVA代码,测试正确
  8. 使用win10自带的计算器,计算对数log
  9. UnicodeTOGB,能够将Unicode串转换成GB码
  10. expdp报DBMS_AW_EXP等信息
  11. WordPress怎么使用支持注册用户上传自定义头像功能?
  12. 微软云计算平台AppFabric即将上市
  13. R语言中的factor
  14. 防蓝光的台灯有用吗?2022最新的防蓝光台灯品牌排行榜
  15. 阿里云国际站:互联网云巨头增速放缓 SaaS生态决胜未来?
  16. java网上商城学年论文_java网上商城论文(DOC毕业设计论文)
  17. 多叉树的递归和非递归遍历
  18. 计算机网络三之以太网
  19. pdf编辑器中文版哪个好用
  20. 身边的RFID产品应用

热门文章

  1. 腾讯2014校园招聘笔试试题
  2. Adobe Audition无法播放的解决方案
  3. [译] Say Hello to React CDK
  4. html5 九宫格猜字游戏,HTML5中  九宫格 的编写方法
  5. 我的切图方法最佳实践
  6. BC107 箭形图案
  7. 如何把Issue博客自动同步到github page中
  8. python做雪花飘落_python实现雪花飘落效果实例讲解
  9. 高通蓝牙ADK-- 48k的usb voice
  10. Proteus8.9 VSM Studio WINAVR编译器仿真ATmega16系列a17_正反转可控直流电机