今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:
设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。
同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:
有一个数字串:312, 当N=3,K=1时会有以下两种分法:
312=36
312=62
这时,符合题目要求的结果是:31*2=62
现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。
输入格式
程序的输入共有两行:
第一行共有2个自然数N,K(6≤N≤40,1≤K≤6)
第二行是一个长度为N的数字串。
输出格式
输出所求得的最大乘积(一个自然数)。
样例输入
4 2
1231
样例输出
62``
解题思路:使用dfs进行遍历,探索每一个数字之间是否注入节点(即为 * 号)。
比如说输入
3 1
123
先对1和2之间插入节点,res=1 * 2=2;st=2;node - - ;i=i+1
进入下一层,此处选择不加节点的话,则将res与上一个节点的乘数剥离:res=res/st= 2/2=1,然后st=“2”+“3”=23,再用res去乘新的st,得到res=1 * 23=23
此时node=0,将res放入list中。最后对得到的每一个res进行遍历,取出最大值即可。
为什么用long而不用int
因为我是对每一种情况都进行遍历,当st过大时或者参数超出int的最大值时,会报错java.lang.NumberFormatException(数字格式异常),且参数不能大于10位数字。所以使用了long类型,当然也可以使用
BigInteger。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class chengjizuida {
static int n, k;
static int[] tarr;//用于放置字符串中的各个数字
static List<Integer> list=new ArrayList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] sarr = scanner.nextLine().split(" ");
n = Integer.parseInt(sarr[0]);//有几个数
k = Integer.parseInt(sarr[1]);//有几个节点
String s = scanner.nextLine();
tarr = new int[n];
for (int i = 0; i < n; i++) {
tarr[i] = s.charAt(i) - '0';
}
dfs(0,k,tarr[0],tarr[0]);
int max=0;
for (int i=0;i<list.size();i++){
max=Math.max(max,list.get(i));
}
System.out.println(max);
}
// i表示当前的字数 node表示还剩下多少个节点 res表示截至到当前的i,前面所有数字的乘积大小 st表示从上一个节点到当前i的所有数字的数字串
private static void dfs(int i,int node ,long res,long st ) {
if(node==0){//当节点为0时,将上一个st和余下的数字串合成,再去乘以res
res=res/st;
String str=new String();
for (int j=i;j<n;j++){
str+=tarr[j];
}
res=res*Integer.parseInt(str);
int res1=(int)res;
list.add(res1);
return;
}
if (i+1<n&&tarr[i+1]!=0){//先进行不加节点
i=i+1;
long result1=res/st;
long str=Long.parseLong(st+String.valueOf(tarr[i]));
result1=result1*str;
dfs(i,node,result1,str);
node--;//此处进行加节点的操作
long result2=res*tarr[i];
str=tarr[i];
dfs(i,node,result2,str);
}else if (i+1<n&&tarr[i+1]==0){//这里需要额外判断tarr[i]==0;因为st不能为0(st为除数)
i=i+1;
long result1=res/st;
long str=Long.parseLong(String.valueOf(st)+String.valueOf(tarr[i]));
result1=result1*str;
dfs(i,node,result1,str);
}
}
}
这个方法比较笨,只是自己的一点尝试,要优化的地方还有很多。其实这道题用动态规划来做会更好,此处只是提供另外一种思路,如果有错误,还请拨冗指正,十分感谢!