题解 | #合唱团#

合唱团

http://www.nowcoder.com/practice/661c49118ca241909add3a11c96408c8

#include <iostream>
#include <limits.h>
using namespace std;

int main()
{
 int n,k,d;
 int V[51];
 long long results_max[51][11] = {0};
 long long results_min[51][11] = {0};
    cin>>n;
    for(int i=1;i<=n;i++)
    {
       cin>>V[i]; 
       results_max[i][1] = V[i];
       results_min[i][1] = V[i]; 
    }
    cin>>k>>d;
    for(int i=2;i<=k;i++)
    {
        for(int j=1;j<=n;j++)
        {

            for(int m=max(j-d,1);m<j;m++)
            {
                results_max[j][i] = max(max(results_max[m][i-1]*V[j],results_min[m][i-1]*V[j]),results_max[j][i]);
                results_min[j][i] = min(min(results_max[m][i-1]*V[j],results_min[m][i-1]*V[j]),results_min[j][i]);    
            }

        }
    }
    long long max_res = INT_MIN;
    for(int i=1;i<=n;i++)
    {
      if(results_max[i][k]>max_res){max_res=results_max[i][k];}  
    }
    cout<<max_res<<endl;
 return 0;   
}

本题目是一道典型的“动态规划”问题,什么是动态规划问题呢?我的理解是,对于最终我们所要求取的结果,我们通过求取中间过渡态时的结果,逐步去逼近我们最终想要的结果。最经典的问题当属于求最大面积的问题了。在本问题当中,我们要连续求k个同学的乘积最大值,我们首先分析是否存在过渡态呢?前k-1个同学的所得结果应当是在第k个同学之前,k-1个同学的乘积最大值。因此,我们可以从1开始逐渐去寻找各个同学作为最后一个同学时的乘积最大值,当然因为含有负值,我们还需要考虑最小值。这样的存储结构是最难想到的,我们可以选择一个尽量容量比较大的存储结构,多存储一些情况,基本上二维的存储结构就差不多了。另外,由于涉及到乘积,而且是多达几十次的乘积,我们需要使用long long的数据类型。

全部评论

相关推荐

10-15 16:27
门头沟学院 C++
LeoMoon:建议问一下是不是你给他付钱😅😅
点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务