【错题集-编程题】合唱团(动态规划 - 线性 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;
}

三、反思与改进

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


相关文章
|
存储 人工智能 算法
【算法分析与设计】动态规划(下)(一)
【算法分析与设计】动态规划(下)
|
2月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
174 0
|
6月前
|
存储 索引
每日刷题——相遇、宝石(模拟+数学)、相助(模拟+数组)、相依(dp的优化)
每日刷题——相遇、宝石(模拟+数学)、相助(模拟+数组)、相依(dp的优化)
43 1
|
7月前
|
算法 测试技术 C++
【动态规划 状态机dp 性能优化】3098. 求出所有子序列的能量和
【动态规划 状态机dp 性能优化】3098. 求出所有子序列的能量和
【动态规划 状态机dp 性能优化】3098. 求出所有子序列的能量和
|
7月前
【编程题-错题集】连续子数组最大和(动态规划 - 线性 dp)
【编程题-错题集】连续子数组最大和(动态规划 - 线性 dp)
|
7月前
【错题集-编程题】不相邻取数(动态规划 - 线性 dp)
【错题集-编程题】不相邻取数(动态规划 - 线性 dp)
|
7月前
|
Shell 网络安全
【错题集-编程题】mari和shiny(动态规划-多源状态线性 dp)
【错题集-编程题】mari和shiny(动态规划-多源状态线性 dp)
|
7月前
【错题集-编程题】删除相邻数字的最大分数(动态规划 - 线性 dp)
【错题集-编程题】删除相邻数字的最大分数(动态规划 - 线性 dp)
【动态规划入门】动态规划思路五部曲_斐波那契_爬楼梯_最小花费爬楼梯
【动态规划入门】动态规划思路五部曲_斐波那契_爬楼梯_最小花费爬楼梯
79 0
|
存储 算法
【算法分析与设计】动态规划(下)(三)
【算法分析与设计】动态规划(下)