zoukankan      html  css  js  c++  java
  • 算法训练 最大的算式

    问题描述
      题目很简单,给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大。因为乘号和加号一共就是N-1个了,所以恰好每两个相邻数字之间都有一个符号。例如:
      N=5,K=2,5个数字分别为1、2、3、4、5,可以加成:
      1*2*(3+4+5)=24
      1*(2+3)*(4+5)=45
      (1*2+3)*(4+5)=45
      ……
     
    输入格式
      输入文件共有二行,第一行为两个有空格隔开的整数,表示N和K,其中(2<=N<=15, 0<=K<=N-1)。第二行为 N个用空格隔开的数字(每个数字在0到9之间)。
    输出格式
      输出文件仅一行包含一个整数,表示要求的最大的结果
    样例输入
    5 2
    1 2 3 4 5
    样例输出
    120
    样例说明
      (1+2+3)*4*5=120
     
     
    解题思路:dp[i][j]表示前i个数使用j个乘号的最大值。
    状态转移方程:dp[i][j]=max(dp[i][j],dp[p-1][j-1]*(dp[i][0]-dp[p-1][0]));   p表示第j个乘号在第p个数前面;
    方程的意思是:前面i个数使用j个乘号的最大值等于前面p-1个数使用j-1个乘号的最大值乘以后面所有数的和;所以p前面的乘号是最后一个乘号,通过循环最后一个乘号的位置找到最大值;
    (需要注意的是:例如需要5个乘号,最后一个乘号会从第2个数前面开始循环,这时dp[p-1][j-1]就是dp[1][4],显然前面一个数不可能有4个乘号,所以dp[1][4]不存在,但dp[1][4]开始时被初始化为0,这样就不需要担心这种情况的成为最大值)
    #include <string.h>
    #include<iostream>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include <algorithm>
    #include<math.h>
    #define INF 1<<30
    using namespace std;
    long long dp[20][20];
    int main()
    {
       int n,k;
       cin>>n>>k;
       long long sum=0,s;
       for(int i=1;i<=n;i++){
            cin>>s;
            sum+=s;
            dp[i][0]=sum;
       }
       for(int i=1;i<=n;i++){
            for(int j=1;j<=i-1&&j<=k;j++){
                for(int p=2;p<=i;p++){
                    dp[i][j]=max(dp[i][j],dp[p-1][j-1]*(dp[i][0]-dp[p-1][0]));
                }
            }
       }
       cout<<dp[n][k]<<endl;
        return 0;
    }
  • 相关阅读:
    mysql 性能优化方案
    MYSQL 优化常用方法
    MongoDB集群架构及搭建
    memcache分布式 [一致性hash算法] 的php实现
    memcache 的内存管理介绍和 php实现memcache一致性哈希分布式算法
    【转】linux 查看进程启动路径
    centos7 编译安装nginx+tcp+grpc转发
    mongodb笔记
    【转】mysql 解事务锁
    【转】centos7 搭建etcd集群
  • 原文地址:https://www.cnblogs.com/zdl2234/p/10391840.html
Copyright © 2011-2022 走看看