网易笔试题之合唱团---动态规划

动态规划学习

[编程题]合唱团

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

输入描述:
每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <= 50)。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。
输出描述:
输出一行表示最大的乘积。
输入例子:
3
7 4 7
2 50
输出例子:
49

思路:

分析:该题目是一个动态规划的问题,那么我们首先要构造出状态转移方程。不妨设maxVal[i][j]表示以第i个人为最后一个(前面共i个人,最后一个人必选),一共选取了j个人(包含i)时的最大乘积。

同理,minVal[i][j]表示同样状态下的最小乘积(由于数据中存在负数,负数乘上某个极大的负数反而会变成正的极大值,因而需要同时记录最小值)。maxVal[i][j]很显然与maxVal[i][j-1]相关,可以理解为maxVal[i][j]由两部分组成,一部分是自身作为待选值,另一部分是maxVal[i][j-1]加上一个人后得到的值,然后取它们的极大值,由此可以得到状态转移方程如下:

maxVal[i][j] = max(maxVal[i][j], max(maxVal[c][j - 1] * a[i], minVal[c][j - 1] * a[i]));

minVal[i][j] = min(minVal[i][j], min(maxVal[c][j - 1] * a[i], minVal[c][j - 1] * a[i]));

最后遍历Maxval[i][k]即可得到最大值。

#include <iostream>
#include <algorithm>
using namespace std;
//因为题目的取值范围最多50个人,最多选10个。所以数组长度分别取51,11
long long maxVal[51][11];
//存放当前选取第i个人(已经选了j个人)最大值记录。(第i个人必选)
long long minVal[51][11];
//存放当前选取第i个人(已经选了j个人)最小值记录。(第i个人必选)

int a[51];
//存放个人能力值
int main(void)
{
	int N, K, D;
	long long result = 0;
	//返回输出结果

	cin >> N;

	for (int i = 0; i < N; ++i)
	{
		cin >> a[i];
	}

	cin >> K >> D;

	for (int i = 0; i < N; ++i)
	{
		maxVal[i][0] = minVal[i][0] = a[i];
	}

	for (int i = 0; i < N; ++i)
	{
		for (int j = 1; j < K; ++j)
		{
			for (int c = i - 1; c >= max(i - D,0); --c)
			{
				maxVal[i][j] = max(maxVal[i][j], max(maxVal[c][j - 1] * a[i], minVal[c][j - 1] * a[i]));
				minVal[i][j] = min(minVal[i][j], min(maxVal[c][j - 1] * a[i], minVal[c][j - 1] * a[i]));
			}
		}
		result = max(result, max( maxVal[i][K - 1] ,minVal[i][K - 1]) );
	}

	cout << result << endl;
	getchar();
	return 0;
}

动态规划学习总结:

思路:

把大问题转化成小问题,先满足当前条件,然后转移到下一个k,判断k是否要被选择,判断依据是是否比上一次更优解。然后依次转移,直到最后选择出最优解。

个人理解,还不深入,再我进行多练习之后再加总结。

2016-08-31 15:17:10

时间: 2024-10-28 06:19:48

网易笔试题之合唱团---动态规划的相关文章

python 饥饿的小易(网易笔试题)

本周早些时候,学弟给我发了一道网易的笔试题,饥饿的小易,感觉有点意思-分享给大家 题目描述: 小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃.最开始小易在一个初始位置x_0.对于小易所处的当前位置x,他只能通过神秘的力量移动到 4 * x + 3或者c.因为使用神秘力量要耗费太多体力,所以它只能使用神秘力量最多100,000次.贝壳总生长在能被1,000,000,007整除的位置(比如:位置0,位置1,000,000,007,位置2,000,000,014等).小易需要你帮忙计算最少需要

网易笔试题

1.小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3...bn. 如果遇到的怪物防御力bi小于等于小易的当前能力值c,那么他就能轻松打败怪物,并 且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi 与c的最大公约数.那么问题来了,在一系列的锻炼后,小易的最终能力值为多少? 1 #include<iostream> 2 #include<

路灯 -- 2016网易笔试题

题目: 一条长l的笔直的街道上有n个路灯,若这条街的起点为0,终点为l,第i个路灯坐标为ai,每盏灯可以覆盖到的最远距离为d,为了照明需求,所有灯的灯光必须覆盖整条街,但是为了省电,要是这个d最小,请找到这个最小的d. 输入描述: 每组数据第一行两个整数n和l(n大于0小于等于1000,l小于等于1000000000大于0).第二行有n个整数(均大于等于0小于等于l),为每盏灯的坐标,多个路灯可以在同一点. 输出描述: 输出答案,保留两位小数.   输入例子: 7 1515 5 3 7 9 14

网易笔试题:推箱子

大家一定玩过“推箱子”这个经典的游戏.具体规则就是在一个N*M的地图上,有1个玩家.1个箱子.1个目的地以及若干障碍,其余是空地.玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去.如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里.当箱子被推到目的地以后,游戏目标达成.现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成. 输入描述: 每个测试输入包含1个测试用例 第一行输入两个数字N,M表示地图

网易笔试题:找出指定区间数列中能被3整除的个数

题目描述:给定一个数列:1,12,123,...,12345678910,1234567891011...,找出指定区间能被3整除的个数. 输入描述:输入两个数字l和r,代表数列的第l个数和第r个数 输入描述:输出区间内能被三整除的个数 例:输入:2 5 输出:3 因为12,123,1234,12345中能被3整除的有3个. 思路:该题涉及的数字比较大,不能直接用整形或是长整型来存储数字,可以用字符串来存储数字,判定能否被3整除的方法就是看将数字各位的数相加得到的数能否被3整除. 代码如下: #

网易笔试题??

题意 n个物品,背包容量w,问共有多少种放法(n≤30) 分析 折半枚举即可 题意 x<=n y<=n x%y>=k  输入n ,k 问有多少对x y满足条件(n 取到10^5) 分析 从k+1枚举y,记录下每个y的x的数量即可 原文地址:https://www.cnblogs.com/Superwalker/p/8660898.html

网易笔试题_塔的最小不稳定性

原题不再赘述,大概就是这么个意思: 输入n个数(均大于0)以及可以对这n个数进行操作的最多次数,每次操作将n个数中最大值-1,最小值+1,计算进行这样的操作后数组中(最大值-最小值)的最小值. java简单实现(暴力解) 1 package interview.test; 2 3 import java.util.*; 4 5 /** 6 * Created by BUAA514 on 2018-08-11. 7 */ 8 public class Main { 9 10 /** 11 * 题目

&lt;转&gt;网易2016实习生前端笔试题部分总结

网易2016实习生前端笔试题部分总结 原文地址:http://www.cnblogs.com/venoral/p/5325202.html 这只是部分题,答案为个人观点如有错误欢迎指出,感觉考点都挺基础,但是很注重考细节方面,通过整理也知道自己在CSS3和HTML5,网络知识等方面的不足还是得多学多练多思考.攒rp,希望自己在明天360笔试中能轻松答过~ css 1.多选 //HTML <p>很长的一段文字,很长的一段文字,很长的一段文字,特别长的文字</p> //CSS p{ w

DP - 2016网易杭研笔试题A

2016网易杭研笔试题A Problem's Link ---------------------------------------------------------------------------- Mean: 有一个边长为n的立方体,内部的每一个小立方体内有一个数字.如果取了当前这个小立方体,则小立方体的: 1.上下相邻两层将会消失; 2.前后相邻两列将会消失; 3.左右相邻两个将会消失; 找出一种取法,使得取到的数的sum最大,输出sum. analyse: 现场面试时挂在这题上了