问题描述
题目很简单,给出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。据说搜索也可以
设
dp[l][r][k]
d
p
[
l
]
[
r
]
[
k
]
为讲区间坐标l到r的数值进行操作,并且用了k个乘号的最大值。限制条件
r−l>=k
r
−
l
>=
k
转移f方程:
如果没用乘法:
如果用了乘号:
但是这种写法,莫名有一个case过不了,想不明白。
代码
import java.util.Arrays;
import java.util.Scanner;
public class Main
{
static int dp[][][]=new int[30][30][30];
static int n,k;
static int solve(int l,int r,int num)
{
if(dp[l][r][num]!=-1)
return dp[l][r][num];
int temp=0;
for(int mid=l;mid<r;mid++)
{
for(int mid2=0;mid2<=num;mid2++)
if(mid-l>=mid2&&r-mid-1>=num-mid2)
temp=Math.max(temp, solve(l,mid,mid2)+solve(mid+1,r,num-mid2));
for(int mid2=0;mid2<=num-1;mid2++)
if(mid-l>=mid2&&r-mid>=num-mid2)
temp=Math.max(temp, solve(l,mid,mid2)*solve(mid+1,r,num-1-mid2));
}
return dp[l][r][num]=temp;
}
public static void main(String[] args)
{
Scanner sc= new Scanner(System.in);
System.out.println();
n=sc.nextInt();
k=sc.nextInt();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
Arrays.fill(dp[i][j], -1);
for(int i=1;i<=n;i++)
dp[i][i][0]=sc.nextInt();
System.out.println(solve(1,n,k));
}
}