最佳加法表达式
总时间限制:
1000ms
内存限制:
65536kB
描述
给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值。例如,在1234中摆放1个加号,最好的摆法就是12+34,和为36
输入
有不超过15组数据
每组数据两行。第一行是整数m,表示有m个加号要放( 0<=m<=50)
第二行是若干个数字。数字总数n不超过50,且 m <= n-1
输出
对每组数据,输出最小加法表达式的值
样例输入
2
123456
1
123456
4
12345
样例输出
102
579
15
提示
要用到高精度计算,即用数组来存放long long 都装不下的大整数,并用模拟列竖式的办法进行大整数的加法。
来源
Guo Wei
郭老师的一个BT题目。动态规划就算了吧,还要用到高精度计算!做这个题目真的是不会了,c++在这个高精度计算上卡住了,幸亏有java,使用Math包中的BigInteger完成高精度计算。
- 参考代码(java):
import java.util.*;
import java.math.*;
public class Best_add_method {
static String expression;
static BigInteger[][] num = new BigInteger[55][55];
public static final BigInteger INF = new BigInteger("9999999999999999999999999999999999999999999999999999999");
static BigInteger V(int m,int n)
{
if(m == 0)//无加号
return num[1][n];
else if(n < m+1)//加号过多
return INF;
else
{
BigInteger t = INF;
for(int i = m;i <= n-1;i++)
t = t.min(num[i+1][n].add(V(m-1,i))); // V(m-1,i)+num[i+1][n]
return t;
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int m,n;
while( input.hasNext() )
{
m = input.nextInt();
expression = input.next();
n = expression.length();
//预处理,计算i到j数字串组成的数字
for(int i = 1;i <= n;i++)
{
num[i][i] = new BigInteger(expression.substring(i-1, i));//只有一个数字
//System.out.println(num[i][i]);
for(int j = i+1;j <= n;j++)
{
num[i][j] = new BigInteger(expression.substring(i-1, j));
//System.out.println(num[i][j]);
}
}
System.out.println(V(m,n));
}
}
}
用到的函数
- substring():substring() 方法用于提取字符串中介于两个指定下标之间的字符。
stringObject.substring(start,stop)
返回值:一个新的字符串,该字符串值包含 stringObject 的一个子字符串,
其内容是从 start 处到 stop-1 处的所有字符,其长度为 stop 减 start。
start | 必需。一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置。 |
---|---|
stop | 可选。一个非负的整数,比要提取的子串的最后一个字符在 stringObject 中的位置多 1。如果省略该参数,那么返回的子串会一直到字符串的结尾。 |
- BigInteger():
- 在Java中,由CPU原生提供的整型最大范围是64位long型整数。使用long型整数可以直接通过CPU指令进行计算,速度非常快。
如果我们使用的整数范围超过了long型怎么办?这个时候,就只能用软件来模拟一个大整数。java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数:
BigInteger bi = new BigInteger("1234567890");
System.out.println(bi.pow(5)); // 2867971860299718107233761438093672048294900000
- 对BigInteger做运算的时候,只能使用实例方法,例如,加法运算:
BigInteger i1 = new BigInteger("1234567890");
BigInteger i2 = new BigInteger("12345678901234567890");
BigInteger sum = i1.add(i2); // 12345678902469135780