题目描述 有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,
要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大
的乘积吗? 输入描述: 每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学
生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <= 50)
。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。
此考察的是动态规划问题,C++代码如下
/*! * file test.cpp * date 2018/02/07 15:37 * * author sunicey * Contact: sunicey@happy.com * * rief 动态规划 * * TODO: 动态规划处理合唱问题 * * ote */ //导入头文件 #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { //input the number of pepole int n; cin >> n; //创建一个容器来存储权值 vector<long long> a(n + 1); //顺序输入权值 for (int i = 1;i <= n;i++) { cin >> a[i]; } //输入合唱的人数以及相邻间隔的差值 int k, d; cin >> k >> d; //创建两个二维容器来存储相对应的最大值以及最小值 //如max_weight[i][j]表示总人数的第i个人作为被挑选的第j人 vector<vector<long long> > max_weight(n + 1, vector<long long>(k + 1, 0)); vector<vector<long long> > min_weight(n + 1, vector<long long>(k + 1, 0)); //设一最小值 long long res = LLONG_MIN; //开始处理,需要建立三层循环,也可以两层循环 for (int i = 1;i <= n;i++) { max_weight[i][1] = min_weight[i][1] = a[i]; //代表第i个人可被挑选的第j个人,此时必须要求i>=j for (int j = 2;j <= k && j <= i;j++) { //此时处理相邻被挑选的人不能超过d for (int s = 1;s <= d && i - s >= 1;s++) { max_weight[i][j] = max(max_weight[i][j], max(max_weight[i - s][j - 1] * a[i], min_weight[i - s][j - 1] * a[i])); min_weight[i][j] = min(min_weight[i][j], min(max_weight[i - s][j - 1] * a[i], min_weight[i - s][j - 1] * a[i])); } } res = max(res, max_weight[i][k]); } for (int i = 1;i <= n;i++) { for (int j = 1;j <= k;j++) { cout << max_weight[i][j] << " "; } cout << endl; } cout << res << endl; system("pause"); return 0; }
如下测试输出:
python代码
n = int(input()) arr = map(int,input().split()) k,d = map(int,input().split()) arr = list(arr) fm = [([0]*k) for i in range(n)] fn = [([0]*k) for i in range(n)] res=0 for i in range(0,n):#the ith 0~n-1 fm[i][0] = arr[i] fn[i][0] = arr[i] for j in range(1,min(i,k)): for s in range(1,min(d+1,i)): fm[i][j] = max(fm[i][j],max(fm[i-s][j-1]*arr[i],fn[i-s][j-1]*arr[i])) fn[i][j] = min(fn[i][j],min(fm[i-s][j-1]*arr[i],fn[i-s][j-1]*arr[i])) res=max(res,fm[i][k-1]) print (res)