题意:有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?


思路:表示在i个位置选了j人的最大乘积,表示在i个位置选了j人的最小乘积。为什么要记录最小乘积?因为每个学生的能力值可能为正可能为负,那么必须保存最小乘积,才能保证不遗漏负数相乘的情况。


AC代码

#include <stdio.h>
#include <algorithm>
using namespace std;
#define inf 1e14
typedef long long LL;
typedef pair<LL, LL> pii;
const int maxn = 50+5;
//d(i, j, 1)表示在i个位置选了j人的最大乘积
//d(i, j, 1)表示在i个位置选了j人的最小乘积
LL dp[maxn][15][2];
int a[maxn];

int main() {
    int n, cnt, d;
    while(scanf("%d", &n) == 1) {
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            dp[i][1][1] = dp[i][1][0] = a[i];
        }
        scanf("%d%d", &cnt ,&d);
        for(int i = 1; i <= n; i++) {
            for(int j = 2; j <= min(cnt, i); j++) {
                dp[i][j][1] = -inf,
                dp[i][j][0] = inf;
                for(int k = i-1; k > 0 && k >= i-d && k >= j-1; k--) {
                    for(int q = 0; q < 2; q++) {
                        dp[i][j][1] = max(dp[i][j][1], dp[k][j-1][q] * a[i]);
                        dp[i][j][0] = min(dp[i][j][0], dp[k][j-1][q] * a[i]);
                    }
                }
            }
        }

        LL ans = -inf;
        for(int i = cnt; i <= n; i++) {
            ans = max(ans, dp[i][cnt][1]);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

如有不当之处欢迎指出!

合唱团 (线性dp)的更多相关文章

  1. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  2. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

  3. hdu1712 线性dp

    //Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...

  4. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  5. POJ 2479-Maximum sum(线性dp)

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33918   Accepted: 10504 Des ...

  6. poj 1050 To the Max(线性dp)

    题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...

  7. nyoj44 子串和 线性DP

    线性DP经典题. dp[i]表示以i为结尾最大连续和,状态转移方程dp[i] = max (a[i] , dp[i - 1] + a[i]) AC代码: #include<cstdio> ...

  8. 『最大M子段和 线性DP』

    最大M子段和(51nod 1052) Description N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M &g ...

  9. 『最长等差数列 线性DP』

    最长等差数列(51nod 1055) Description N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不 ...

随机推荐

  1. linkinFrame--测试项目添加git管理

    OK,前面一篇博客,已经搭建好了项目的基础的结构.现在我们添加一个简单的servlet来测试下项目能不能跑,然后在讲项目添加到coding上用git管理. 1,我们编写一个servlet,编写一个js ...

  2. HashiCorp Vault介绍

    HashiCorp Vault是一款企业级私密信息管理工具.说起Vault,不得不提它的创造者HashiCorp公司.HashiCorp是一家专注于DevOps工具链的公司,其旗下明星级产品包括Vag ...

  3. 汉诺塔python3函数编写和过程分析

    !/usr/bin/env python3 -- coding: utf-8 -- 利用递归函数计算阶乘 N! = 1 * 2 * 3 * ... * N def fact(n): if n == 1 ...

  4. awk打印第n个参数到最后一个技巧/将n行组成一列

    打印第n参数到最后一个参数 文本的NF不等,即字段长度不固定,想截取从$3到$NF 第一反应是使用循环 [root@localhost ~]# echo "1 2 3 4 5" | ...

  5. Node-debug方法

    本文使用配置node-inspector配合chorme完成debug(编辑器使用SublimeText3). 1.用命令行进入安装node的目录,使用npm install -g node-insp ...

  6. Apache自带的rotatelogs实现日志轮转

    用Apache自带的rotatelogs程序处理apache生成的日志自动截断重新生成,rotatelogs是一个配合Apache管道日志功能使用的简单程序.设置方法如下: 编辑Apache的主配置文 ...

  7. ansible playbook实践(四)-如何调试写好的playbook文件

    有时,我们写了一个长长,功能很强悍的yaml文件,但是,我们有可能会担心,写的yaml文件是否正确,是否有漏洞危机,毕竟是要修改线上的机器,那么,有可能我们可以从以下几个检查维度来进行,确保在大规模应 ...

  8. BZOJ 3512: DZY Loves Math IV [杜教筛]

    3512: DZY Loves Math IV 题意:求\(\sum_{i=1}^n \sum_{j=1}^m \varphi(ij)\),\(n \le 10^5, m \le 10^9\) n较小 ...

  9. POJ 3182 The Grove [DP(spfa) 射线法]

    题意: 给一个地图,给定起点和一块连续图形,走一圈围住这个图形求最小步数 本来是要做课件上一道$CF$题,先做一个简化版 只要保证图形有一个点在走出的多边形内就可以了 $hzc:$动态化静态的思想,假 ...

  10. php语言基础(一)

    一.php标记风格 1.1xml风格(常用) <?php echo "xml风格": ?> 1.2脚本风格 <script language="php& ...