算法设计与分析: 3-16 最大k乘积问题

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值