zoukankan      html  css  js  c++  java
  • 洛谷 P1018乘积最大

    题目描述

    今年是国际数学联盟确定的“20002000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰9090周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZXZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:

    设有一个长度为NN的数字串,要求选手使用KK个乘号将它分成K+1K+1个部分,找出一种分法,使得这K+1K+1个部分的乘积能够为最大。

    同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:

    有一个数字串:312312, 当N=3,K=1N=3,K=1时会有以下两种分法:

    1、3 imes 12=363×12=36 2、31 imes 2=6231×2=62

    这时,符合题目要求的结果是: 31 imes 2 = 6231×2=62

    现在,请你帮助你的好朋友XZXZ设计一个程序,求得正确的答案。

    输入输出格式

    输入格式:

    程序的输入共有两行:

    第一行共有22个自然数N,KN,K(6≤N≤40,1≤K≤66N40,1K6)

    第二行是一个长度为NN的数字串。

    输出格式:

    结果显示在屏幕上,相对于输入,应输出所求得的最大乘积(一个自然数)。

    输入输出样例

    输入样例#1: 复制
    4  2
    1231
    
    输出样例#1: 复制
    62

    分析:

    一个很明显的dp问题,但是数字因为结果数字太大,所以要用到大数类,就是Biginteger。

    我开辟了一个二维数组 res[k+1][len+1] ,其中 k+1 是用到了几个乘号,len 就是记录最后一个数字的位置。

    动态转移方程很简单:dp[n][m]=Math.max(dp[n][m],dp[n-1][m]*最后一个要乘的数字);

    代码:

     1 import java.math.BigInteger;
     2 import java.util.Scanner;
     3 
     4 public class Main {
     5     public static void main(String args[]) {
     6         Scanner sc=new Scanner(System.in);
     7         int num=sc.nextInt();
     8         int k=sc.nextInt();
     9         String str=sc.next();
    10         int len=str.length();
    11         BigInteger[][] res=new BigInteger[k+1][len+1];
    12         for(int n=1;n<=len;++n)
    13             res[0][n]=new BigInteger(str.substring(0,n));
    14         for(int i=1;i<=k;++i)
    15             for(int j=1;j<=len;++j) 
    16                 for(int n=j-1;n>0;--n) {
    17                     if(res[i-1][n]==null)
    18                         continue;
    19                     BigInteger b=new BigInteger(str.substring(n,j));
    20                     BigInteger r=res[i-1][n].multiply(b);
    21                     if(res[i][j]==null)
    22                         res[i][j]=r;
    23                     else
    24                         res[i][j]=res[i][j].max(r);
    25                 }
    26         System.out.print(res[k][len]);
    27     }
    28 }

    其中有一个判定大数为空的话,就直接跳过的if语句。首先开辟的大数数组和int数组是一样的,他的初始值不是0而是null,所以如果你不给他赋值的话他就是null,是无法计算的。

    如果当前数组位置为null的话,就说明不会有这种情况,比如res[2][1],你只有长度为1的数字,是无论如何也无法用两个乘号去运算的,所以直接跳过就可以了,不必纠结。

  • 相关阅读:
    随机森林算法参数调优
    BAYES和朴素BAYES
    阿里云 金融接口 token PHP
    PHP mysql 按时间分组 表格table 跨度 rowspan
    MySql按周,按月,按日分组统计数据
    PHP 获取今日、昨日、本周、上周、本月的等等常用的起始时间戳和结束时间戳的时间处理类
    thinkphp5 tp5 会话控制 session 登录 退出 检查检验登录 判断是否应该跳转到上次url
    微信 模板消息
    php 腾讯 地图 api 计算 坐标 两点 距离 微信 网页 WebService API
    php添加http头禁止浏览器缓存
  • 原文地址:https://www.cnblogs.com/CHAHA123/p/10820799.html
Copyright © 2011-2022 走看看