【错题集-编程题】合唱团(动态规划 - 线性 dp)

简介: 【错题集-编程题】合唱团(动态规划 - 线性 dp)

牛客对应题目链接:合唱团_牛客题霸_牛客网 (nowcoder.com)


一、分析题目

线性 dp


1、状态表示

f[i][j]:从前 i 个人中挑选出 j 个人,arr[i] 必选的最大乘积。

g[i][j]:从前 i 个人中挑选出 j 个人,arr[i] 必选的最小乘积。


2、返回值

返回 max(f[k][k] ~ f[n][k])


3、状态转移方程

f[i][j] = max(f[prev][j-1] * arr[i], g[prev][j-1] * arr[i]);(max(i-d, j-1) <= prev <= i-1)

f[i][j] = min(f[prev][j-1] * arr[i], g[prev][j-1] * arr[i]);(max(i-d, j-1) <= prev <= i-1)


4、初始化

  • f[i][j]=-INF,g[i][j]=INF(避免影响后续取值)
  • f[i][1] = g[i][1] = arr[i]

注意:这里的取值范围很大,所以要用到 long long 来存储结果,那么这里的 INF 可以设为 LLONG_MAX 或 0x3f3f3f3f3f3f3f3f。


二、代码

//值得学习的代码
#include <iostream>
using namespace std;
 
typedef long long LL;
 
const int N = 55, M = 15;
const LL INF = 0x3f3f3f3f3f3f3f3f;
 
int n, k, d;
LL arr[N];
LL f[N][M], g[N][M];
 
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> arr[i];
    cin >> k >> d;
 
    // 初始化放在填表中进⾏了
 
    for(int i = 1; i <= n; i++) // 填写每⼀⾏
    {
        g[i][1] = f[i][1] = arr[i];
        for(int j = 2; j <= min(i, k); j++) // 挑选⼏个⼈
        {
            f[i][j] = -INF; // 初始化
            g[i][j] = INF; // 初始化
            for(int prev = max(i - d, j - 1); prev <= i - 1; prev++) // 前⾯挑选的最后⼀个位置
            {
                f[i][j] = max(max(f[prev][j - 1] * arr[i], g[prev][j - 1] * arr[i]), f[i][j]);
                g[i][j] = min(min(f[prev][j - 1] * arr[i], g[prev][j - 1] * arr[i]), g[i][j]);
            }
        }
    }
 
    LL ret = -INF;
    for(int i = k; i <= n; i++) ret = max(ret, f[i][k]);
    cout << ret << endl;
 
    return 0;
}

三、反思与改进

这题真没有思路,加上前面的题目也没有通过全部样例,有点影响对这道题的思考。认真反思,汲取经验。


相关文章
|
存储 人工智能 算法
【算法分析与设计】动态规划(下)(一)
【算法分析与设计】动态规划(下)
|
1月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
101 0
|
6月前
【编程题-错题集】连续子数组最大和(动态规划 - 线性 dp)
【编程题-错题集】连续子数组最大和(动态规划 - 线性 dp)
|
6月前
【错题集-编程题】不相邻取数(动态规划 - 线性 dp)
【错题集-编程题】不相邻取数(动态规划 - 线性 dp)
|
6月前
|
Shell 网络安全
【错题集-编程题】mari和shiny(动态规划-多源状态线性 dp)
【错题集-编程题】mari和shiny(动态规划-多源状态线性 dp)
|
6月前
【编程题-错题集】分割等和子集(动态规划 - 01背包)
【编程题-错题集】分割等和子集(动态规划 - 01背包)
|
6月前
【错题集-编程题】删除相邻数字的最大分数(动态规划 - 线性 dp)
【错题集-编程题】删除相邻数字的最大分数(动态规划 - 线性 dp)
|
消息中间件 人工智能 算法
【算法分析与设计】动态规划(下)(二)
【算法分析与设计】动态规划(下)
|
存储 算法
【算法分析与设计】动态规划(下)(三)
【算法分析与设计】动态规划(下)
|
算法 Android开发
LeetCode 周赛上分之旅 #41 结合离散化的线性 DP 问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
74 0