原题链接:用户登录
题目描述
今年是国际数学联盟确定的“2000 --世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰 90 周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友 XZ 也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:
设有一个长度为 N 的数字串,要求选手使用 K 个乘号将它分成K + 1 个部分,找出一种分法,使得这 K + 1 个部分的乘积能够为最大。
同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:
有一个数字串:312,当 N =3,K =1 时会有以下两种分法:
1.3 x 12 =36
2.31 x 2 = 62
这时,符合题目要求的结果是: 31 X 2 =62
现在,请你帮助你的好朋友 XZ 设计一个程序,求得正确的答案。
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int k = scan.nextInt();
String s = scan.next();
int [] a = new int[n+1];
for(int i = 0; i < s.length(); i++) { // 获取s每一位上的值
a[i+1] = s.charAt(i) - '0';
}
int[][] dp = new int[n+1][k+1];
int[][] v = new int[n+1][n+1];
for(int i = 1; i <= n; i++) {//v[i][j]表示 从i到j构成的数
for (int j = i; j <= n; j++) {
v[i][j] = v[i][j-1] * 10 + a[j];
}
}
for(int i = 1; i <= n; i++) {//初始化,0个乘号时即为1到i数的大小
dp[i][0] = v[1][i];
}
for(int t = 1; t <= k; t++) { // t个乘号
for(int i = 1; i <= n; i++) {
for (int j = 1; j < i; j++) {
dp[i][t] = Math.max(dp[i][t], dp[j][t-1] * v[j+1][i]);
}
}
}
System.out.println(dp[n][k]);
scan.close();
}
}
其中char-“0”的含义
ASCII码48就是'0',也就是说'0'的值是48,而后依次是'1'到'9'。 这样正好是char型减去48就是它对应的int值。
v的值即(以1231为例):
1 | 12 | 123 | 1231 | |
2 | 23 | 231 | ||
3 | 31 | |||
1 |
初始dp的值:
1 | ||
12 | ||
123 | ||
1231 |
运算之后dp的值: