• 合唱团--动态规划


    题目描述
    有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,
    要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大
    的乘积吗? 输入描述: 每个输入包含
    1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学
    生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <= 50
    。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。

    此考察的是动态规划问题,C++代码如下

    /*!
     * file test.cpp
     * date 2018/02/07 15:37
     *
     * author sunicey
     * Contact: sunicey@happy.com
     *
     * rief 动态规划
     *
     * TODO: 动态规划处理合唱问题
     *
     * 
    ote
    */
    
    
    //导入头文件
    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
    
        //input the number of pepole
        int n;
        cin >> n;
        //创建一个容器来存储权值
        vector<long long> a(n + 1);
        //顺序输入权值
        for (int i = 1;i <= n;i++) {
            cin >> a[i];
        }
        //输入合唱的人数以及相邻间隔的差值
        int k, d;
        cin >> k >> d;
        //创建两个二维容器来存储相对应的最大值以及最小值
        //如max_weight[i][j]表示总人数的第i个人作为被挑选的第j人
        vector<vector<long long> > max_weight(n + 1, vector<long long>(k + 1, 0));
        vector<vector<long long> > min_weight(n + 1, vector<long long>(k + 1, 0));
        //设一最小值
        long long res = LLONG_MIN;
        //开始处理,需要建立三层循环,也可以两层循环
        for (int i = 1;i <= n;i++) {
            max_weight[i][1] = min_weight[i][1] = a[i];
            //代表第i个人可被挑选的第j个人,此时必须要求i>=j
            for (int j = 2;j <= k && j <= i;j++) {
                //此时处理相邻被挑选的人不能超过d
                for (int s = 1;s <= d && i - s >= 1;s++) {
                    max_weight[i][j] = max(max_weight[i][j], max(max_weight[i - s][j - 1] * a[i], min_weight[i - s][j - 1] * a[i]));
                    min_weight[i][j] = min(min_weight[i][j], min(max_weight[i - s][j - 1] * a[i], min_weight[i - s][j - 1] * a[i]));
                }
            }
            res = max(res, max_weight[i][k]);
        }
    
        for (int i = 1;i <= n;i++) {
            for (int j = 1;j <= k;j++) {
                cout << max_weight[i][j] << " ";
            }
            cout << endl;
        }
        cout << res << endl;
        system("pause");
        return 0;
    }

    如下测试输出:

     python代码

    n = int(input())
    arr = map(int,input().split())
    k,d = map(int,input().split())
    arr = list(arr)
    fm = [([0]*k) for i in range(n)]
    fn = [([0]*k) for i in range(n)]
    res=0
    for i in range(0,n):#the ith 0~n-1
        fm[i][0] = arr[i]
        fn[i][0] = arr[i] 
        for j in range(1,min(i,k)):
            for s in range(1,min(d+1,i)):
                fm[i][j] = max(fm[i][j],max(fm[i-s][j-1]*arr[i],fn[i-s][j-1]*arr[i]))
                fn[i][j] = min(fn[i][j],min(fm[i-s][j-1]*arr[i],fn[i-s][j-1]*arr[i]))
        res=max(res,fm[i][k-1])
            
    print (res)
  • 相关阅读:
    存储类&作用域&生命周期&链接属性
    关于mysql数据库的备份和还原
    Centos 7下mysql的安装与配置
    基于Apache+php+mysql的许愿墙网站的搭建
    关于php留言本网站的搭建
    linux下面桌面的安装
    时间同步ntp服务的安装与配置
    通过挂载系统光盘搭建本地yum仓库的方法
    linux系统root用户忘记密码的重置方法
    linux系统的初化始配置
  • 原文地址:https://www.cnblogs.com/lyf-sunicey/p/8427241.html
Copyright © 2020-2023  润新知