3-16 最大k乘积问题
问题描述
设 I 是一个 n 位十进制整数。如果将 I 划分为 k 段,则可得到 k 个整数。这 k 个整数的 乘积称为 I 的一个 k 乘积。试设计一个算法,对于给定的 I 和 k,求出 I 的最大 k 乘积。
数据输入:
第 1 行中有 2 个正整数 n 和 k。正整数 n 是序列 的长度;正整数 k 是分割的段数。接下来的一行中是一个 n 位十进制整数。(n<=10)
Java
import java.util.Scanner;
public class ZuiDaKChengJi {
private static int n,m;
private static String str;
private static int[][] f,ka;
/*
I(s,t): I的由从s位开始的t位数字组成的十进制数
f(i,j): I(0,i)的最大j乘积
f(i,j)=max{f(k,j-1)*I(k,i-k)} (1<=k<i)
*/
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
n = input.nextInt();
m = input.nextInt();
if(n < m || n==0){
System.out.println(0);
return;
}
str = input.next();
if(n != str.length()){
System.out.println(0);
return;
}
f = new int[n+1][m+1];
ka = new int[n+1][m+1];
dynamic();
out();
}
}
private static void dynamic(){
int i,j,k;
int temp,maxt,tk=0;
for(i=1; i<=n; i++)
f[i][1] = conv(0,i);
for(j=2; j<=m; j++)
for(i=j; i<=n; i++){
for(k=1,temp=0; k<i; k++){
maxt = f[k][j-1]*conv(k,i-k);
if(temp < maxt){
temp = maxt;
tk = k;
}
}
f[i][j] = temp;
ka[i][j] = tk;
}
}
private static int conv(int i, int j){
String str1;
if(i < j){
str1 = str.substring(i,j);
}else {
str1 = str.substring(i,i+1);
}
return Integer.parseInt(str1);
}
private static void out(){
System.out.println(f[n][m]);
for(int i=m,k=n; i>=1&&k>0; k=ka[k][i],i--)
System.out.println("f["+k+"]["+i+"]="+f[k][i]);
}
}
Input & Output
2 1
15
15
f[2][1]=15
王晓东《计算机算法设计与分析》(第3版)P94

该博客讨论了如何设计算法解决最大k乘积问题,即给定一个n位整数I和段数k,找到I的最大k段乘积。问题来源于王晓东《计算机算法设计与分析》(第3版),书中提供了Java实现,并给出了输入输出的示例。
3070

被折叠的 条评论
为什么被折叠?



