zhangbaochong

题目:

有 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

思路:采用动态规划

因为有正有负,负负得正,所以要维护两个dp数组,一个存储最大,一个存储最小。
定义fm[k][i]表示当选中了k个学生,并且以第i个学生为结尾,所产生的最大乘积;
        fn[k][i]表示 当选中了k个学生,并且以第i个学生为结尾,所产生的最小乘积;
那么fm[k+1][i+1]=max(fm[k][i]*stu[i+1],fn[k][i]*stu[i+1]),
        即当选中了k个学生后,再选择第i+1编号学生,所产生的最大乘积;
        然而,并不能保证上一次选择的就是第i个学生,所以要遍历子数组fm[k],
        令j从i到1,并且j与i+1之间小于间隔D,遍历fm[k][j],以及fn[k][j];
同理fn[k+1][i+1]=min(fn[k][i]*stu[i+1],fm[k][i]*stu[i+1])。
最后,遍历一遍fm[K][i]求得最大值(i从1~N)。

代码:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <limits.h>
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     int n, k, d;    
10     cin >> n;
11     vector<int> ai(n+1);
12     int temp;
13     //下标从1开始
14     for (int i = 1; i <= n;++i)
15     {
16         cin >> temp;
17         ai[i] = temp;
18     }
19     cin >> k >> d;
20 
21     vector<vector<long long>> maxRes(n + 1, vector<long long>(k + 1));
22     vector<vector<long long>> minRes(n + 1, vector<long long>(k + 1));
23 
24     //max[i][j]表示已第i个学生结尾,包括该学生总共j个的结果
25     
26     for (int i = 1; i <= n; ++i)
27     {
28         maxRes[i][1] = minRes[i][1] = ai[i];
29     }
30 
31     //序列元素原始位置,从1遍历到n
32     for (int iIndex = 1; iIndex <= n; ++iIndex)
33     {
34         //作为候选元素的位置
35         for (int kIndex = 1; kIndex <= k; ++kIndex)
36         {
37             for (int j = iIndex - 1; j > 0 && iIndex - j <= d;--j)
38             {
39                 maxRes[iIndex][kIndex] = max(maxRes[iIndex][kIndex],
40                     max(maxRes[j][kIndex - 1] * ai[iIndex], minRes[j][kIndex - 1] * ai[iIndex]));
41                 minRes[iIndex][kIndex] = min(minRes[iIndex][kIndex],
42                     min(maxRes[j][kIndex - 1] * ai[iIndex], minRes[j][kIndex - 1] * ai[iIndex]));
43             }
44         }
45     }
46 
47     long long ans = LONG_MIN;
48     for (int i = 1; i <= n; ++i)
49     {
50         if (ans < maxRes[i][k])
51             ans = maxRes[i][k];
52     }
53     cout << ans;
54 }

 

分类:

技术点:

相关文章: