蓝桥杯 算法训练 最大的算式

传送门

 算法训练 最大的算式  
时间限制: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
 
 
题意:
 
给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大。
 
852929 陈志阳 最大的算式 03-08 16:36 1.089KB C++ 正确 100 15ms 11.36MB 评测详情
852881 陈志阳 最大的算式 03-08 16:32 1.090KB C++ 错误 55 15ms 11.36MB 评测详情
852878 陈志阳 最大的算式 03-08 16:31 1.090KB C++ 错误 55 15ms 11.36MB 评测详情
852838 陈志阳 最大的算式 03-08 16:27 1.044KB C++ 错误 88 15ms 11.36MB 评测详情
846242 陈志阳 Torry的困惑(基本型) 03-07 17:34 810B C++ 正确 100 31ms 12.82MB 评测详情
846229 陈志阳 Torry的困惑(基本型) 03-07 17:32 788B C++ 运行超时 0 运行超时 84.28MB 评测详情
844016 陈志阳 最大的算式 03-07 11:30 981B C++ 错误 33 0ms 2.589MB 评测详情
 
题解:
也是心塞啊,非要去想有没有什么贪心的结论,导致一直wa
正解就是 记忆化区间dp
 
转移方程:
 1     for(i = l;i <= r -1;i++){
 2         for(cou = 0;cou <= kk - 1;cou++){
 3             ma = max(ma,dfs(l,i,cou) * dfs(i + 1,r,kk - cou - 1) );
 4         }
 5     }
 6     if(l - r != kk){
 7         for(i = l;i <= r -1;i++){
 8             for(cou = 0;cou <= kk;cou++){
 9                 ma = max(ma,dfs(l,i,cou) + dfs(i + 1,r,kk - cou) );
10             }
11         }
12     }

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <map>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 #define N 105
 9 #define ll long long
10 
11 ll dp[N][N][N];
12 ll n,k;
13 ll a[N];
14 ll sum[N];
15 ll ans;
16 
17 ll dfs(ll l,ll r,ll kk)
18 {
19     if(dp[l][r][kk] != -1) return dp[l][r][kk];
20     if(kk == 0){
21         dp[l][r][kk] = sum[r] - sum[l - 1];
22         return dp[l][r][kk];
23     }
24     ll i,cou;
25     ll ma = 0;
26     for(i = l;i <= r -1;i++){
27         for(cou = 0;cou <= kk - 1;cou++){
28             ma = max(ma,dfs(l,i,cou) * dfs(i + 1,r,kk - cou - 1) );
29         }
30     }
31     if(l - r != kk){
32         for(i = l;i <= r -1;i++){
33             for(cou = 0;cou <= kk;cou++){
34                 ma = max(ma,dfs(l,i,cou) + dfs(i + 1,r,kk - cou) );
35             }
36         }
37     }
38     dp[l][r][kk] = ma;
39     return dp[l][r][kk];
40 }
41 
42 int main()
43 {
44     //freopen("in.txt","r",stdin);
45     while(scanf("%I64d%I64d",&n,&k)!=EOF){
46 
47     memset(dp,-1,sizeof(dp));
48     memset(sum,0,sizeof(sum));
49     ll i;
50     for(i = 1;i <= n;i++){
51         scanf("%I64d",&a[i]);
52         sum[i] = sum[i-1] + a[i];
53     }
54     ans = dfs(1,n,k);
55     printf("%I64d
",ans);
56     }
57     return 0;
58 }
 
 
原文地址:https://www.cnblogs.com/njczy2010/p/5254632.html