算法训练 最大的算式

 算法训练 最大的算式  
时间限制:1.0s   内存限制:256.0MB   
问题描述
  题目很简单,给出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
 
注意:动态规划的初始化不要忘记
/*
    注意: 
    1.使用搜索找到乘号的位置
    2.使用动态规划找到最大的值
    3.使用long long对结果进行保存 
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
long long a[20],op[20],n,k,dp[20][20],maxn;
void dfs(int dep,int pos);
void calc();
int main(void){
    cin >> n >> k;
    for(int i=1;i<=n;i++)
        cin >> a[i];
    dfs(1,1);
    cout << maxn; 
    return 0;
} 
void dfs(int dep,int pos){
    if(dep == k+1){
        calc();
    }
    for(int i=pos;i<n;i++){
        op[i]=1;
        if(n-i-1 >= k-dep) dfs(dep+1,i+1);
        op[i]=0;
    }
}
void calc(){
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
        dp[i][i] = a[i];
    for(int len=2;len<=n;len++){
        for(int i=1;i<=n-len+1;i++){
            int j=i+len-1;
            for(int k=i;k<j;k++){
                long long data;
                if(op[k] == 0) data = dp[i][k] + dp[k+1][j];
                if(op[k] == 1) data = dp[i][k] * dp[k+1][j]; 
                dp[i][j]=max(dp[i][j],data);
            } 
        } 
    }
    maxn=max(maxn,dp[1][n]);
}
原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8503987.html