其他分享
首页 > 其他分享> > 4152:最佳加法表达式,考点:动态规划,高精度计算

4152:最佳加法表达式,考点:动态规划,高精度计算

作者:互联网

原题:http://bailian.openjudge.cn/practice/4152/

描述

给定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 都装不下的大整数,并用模拟列竖式的办法进行大整数的加法。

解法

大整数的加法:用一个类来实现

关键在于动规。

dp[m][n]表示在n个数字中插入m个加法所能形成

 

 

 代码如下:(没有预处理Num(i,j),由于懒吧)

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #define INF 1<<30
 6 using namespace std;
 7 class num {
 8 public:
 9     int n;//位数
10     int p[55] = {};
11     num(int inn=0):n(inn){}
12     num(const num&A) {
13         n = A.n;
14         if (n == INF)return;
15         for (int i = 0; i < n; i++)
16             p[i] = A.p[i];
17     }
18     num(string s) {
19         n = s.length();
20         for (int i = 0; i < n; i++)
21             p[i] = s[i] - '0';
22     }
23     num(int inn,int a[]) {
24         n = inn;
25         for (int i = 0; i < n; i++)
26             p[i] = a[n - 1 - i];
27     }
28     num operator+(const num&A) {
29         if (n == INF)
30             return *this;
31         if (A.n == INF)
32             return A;
33         int factora[55] = {}, factorb[55] = {}, result[55] = {};
34         for (int i = 0; i < A.n; i++)
35             factora[A.n - i-1] = A.p[i];
36         for (int i = 0; i < n; i++)
37             factorb[n - 1 - i] = p[i];
38         int maxc = max(n, A.n);
39         for (int i = 0; i < maxc; i++)
40         {
41             int temp = factora[i] + factorb[i] + result[i];
42             result[i] = temp % 10;
43             result[i + 1] += temp / 10;
44         }
45         if (result[maxc] > 0)
46             maxc++;
47         return num(maxc, result);
48     }
49     bool operator <(const num&A) {
50         if (n != A.n)
51             return n < A.n;
52         for (int i = 0; i < n; i++)
53         {
54             if (p[i] != A.p[i])
55                 return p[i] < A.p[i];
56         }
57         return false;
58     }
59     friend ostream&operator<<(ostream&o, const num&A) {
60         for (int i = 0; i < A.n; i++)
61             o << A.p[i];
62         return o;
63     }
64 };
65 num dp[55][55];//dp[i][j]表示在j个数字中插入i个加号能形成的表达式最小值
66 int main()
67 {
68     int m;
69     while (cin >> m) {
70         string s;
71         cin >> s;
72         int len = s.length();
73         for (int i = 1; i <= len; i++) {
74             dp[0][i] = num(s.substr(0, i));
75         }
76         for (int i = 1; i <= m; i++) {
77             for (int j = 1; j <= i; j++)
78                 dp[i][j] = num(INF);
79             for (int j = i + 1; j <= len; j++) {
80                 dp[i][j] = dp[i - 1][i] + num(s.substr(i, j - i));
81                 for (int k = i + 1; k <= j - 1; k++)
82                 {
83                     num temp = dp[i - 1][k] + num(s.substr(k, j - k));
84                     if (temp < dp[i][j])
85                         dp[i][j] = temp;
86                 }
87             }
88         }
89         cout << dp[m][len] << endl;
90     }
91     
92 }

 

标签:4152,输出,数字,整数,考点,加号,加法,include
来源: https://www.cnblogs.com/erable/p/14992087.html