最佳加法表达式(动态规划)

最佳加法表达式

总时间限制:
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));
	    }
	}
}

用到的函数

  1. substring():substring() 方法用于提取字符串中介于两个指定下标之间的字符。
stringObject.substring(start,stop)
返回值:一个新的字符串,该字符串值包含 stringObject 的一个子字符串,
其内容是从 start 处到 stop-1 处的所有字符,其长度为 stop 减 start。
start必需。一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置。
stop可选。一个非负的整数,比要提取的子串的最后一个字符在 stringObject 中的位置多 1。如果省略该参数,那么返回的子串会一直到字符串的结尾。
  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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值