1. 程式人生 > >百練4152:最佳加法表達式(dp+高精度)

百練4152:最佳加法表達式(dp+高精度)

大整數 輸入 println sca ger 最小值 nbsp oid style

描述

給定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 都裝不下的大整數,並用模擬列豎式的辦法進行大整數的加法。

搞了半天的C++高精度,,結果還是可恥地用了java大數。。

 1 import java.math.BigDecimal;
 2 import java.math.BigInteger;
 3 import java.util.Scanner;
 4 
 5 public class Main {
 6     static BigInteger INF = new BigInteger("9999999999999999999999999999999999999999999999999999999");
 7     public static void main(String[] args) {
8 // TODO Auto-generated method stub 9 Scanner sc = new Scanner(System.in); 10 BigInteger dp[][] = new BigInteger[55][55]; 11 int m,n; 12 BigInteger s; 13 14 while(sc.hasNext()) 15 { 16 m = sc.nextInt(); 17 s = sc.nextBigInteger();
18 19 n = s.toString().length(); 20 21 //BigDecimal num[][] = new BigDecimal[n+1][n+1];//num[i][j]表示從s第i個數到第j個數組成的數字 22 /* 23 for(int i = 1;i<=n;++i) 24 for(int j = 0;j<=n;++j) 25 { 26 if(i<=j) 27 { 28 num[i][j] = new BigDecimal(s.toString().substring(i-1,j)); 29 } 30 } 31 */ 32 33 dp[0][0] = new BigInteger("0");//沒有數字沒有加號的最小值是0 34 for(int i = 1;i<=n;++i) 35 { 36 dp[i][0] = new BigInteger(s.toString().substring(0,i));//沒有加號的情況下,最小值就是數字自己 37 } 38 39 for(int i = 0;i<=n;++i) 40 for(int j = 1;j<=m;++j) 41 { 42 43 dp[i][j] = INF; 44 if(i>=j+1)//j個加號能插入i個數字中 45 { 46 for(int k = j;k<i;++k) 47 { 48 dp[i][j] = dp[i][j].min(dp[k][j-1].add(new BigInteger(s.toString().substring(k,i)))); 49 } 50 } 51 } 52 53 System.out.println(dp[n][m]); 54 }//while 55 } 56 57 }

百練4152:最佳加法表達式(dp+高精度)