算法训练 最大的算式
时间限制: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=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
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\n",ans); 56 } 57 return 0; 58 }