最佳加法表达式

总时间限制: 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 都装不下的大整数,并用模拟列竖式的办法进行大整数的加法。

 

算法参考:http://www.cnblogs.com/quintessence/p/7206417.html  使用了高精度

                  http://www.cnblogs.com/Renyi-Fan/p/6970166.html 没有使用高精度,有详细分析

 

假定数字串长度是n,添完加号后,表达式的最后一个加号添加在第 i 个数字后面
那么整个表达式的最小值,就等于在前 i 个数字中插入 m – 1个加号所能形成的最小值,
加上第 i + 1到第 n 个数字所组成的数的值(i从1开始算)。


设V(m,n)表示在n个数字中插入m个加号所能形成
的表达式最小值,那么:
if m = 0
V(m,n) = n个数字构成的整数
else if n < m + 1
V(m,n) = ∞
else
V(m,n) = Min{ V(m-1,i) + Num(i+1,n) } ( i = m … n-1)
Num(i,j)表示从第i个数字到第j个数字所组成的数。数字编号从1开始算。此操作复杂度是O(j-i+1)
总时间复杂度:O(mn2) .(dp二维表已经加号的位置)

 

 1 #include<iostream>
 2 #include<cstdio> 
 3 #include<cstring> 
 4 #include<algorithm> 
 5 using namespace std;
 6 const int INF=0x3f3f3f3f;
 7 const int N=1005;
 8 int a[N],num[N][N],dp[N][N];
 9 //a[N]里面是存数字串
10 //num[i][j]表示数字串a[N]的第i位到第j位之间的数字串表示的数组
11 //dp[i][j]在i个数字中插入j个加号所能形成的表达式最小值
12 int main(){
13     int n,m;
14     while(scanf("%d %d",&n,&m)){
15         for(int i=1;i<=n;i++){
16             scanf("%d",&a[i]);
17         }
18         //预处理,计算i到j数字串组成的数字 
19         for(int i=1;i<=n;i++){
20             num[i][i]=a[i];//只有一个数字 
21             for(int j=i+1;j<=n;j++){
22                 num[i][j]=num[i][j-1]*10+a[j];
23             } 
24         }
25         memset(dp,0x3f,sizeof(dp));
26         for(int i=1;i<=n;i++){
27             dp[0][i]=num[1][i];//无加号时 
28         }
29         //其实就是感觉在那个位置放不放加号 
30         //这里n可以写在m前面。要加一个限制条件n>m,好麻烦,所以m在前且n=m+1
31         //这里k的取值范围就是m到n,k表示在第k个数后面插入加号 
32         for(int i=1;i<=m;i++)
33             for(int j=i;j<=n;j++)
34                 for(int k=i;k<=j;k++)
35                     dp[i][j]=min(dp[i][j],dp[i-1][k]+num[k+1][j]); 
36         cout<<dp[m][n]<<endl; 
37     }
38 }
未使用高精度的代码

相关文章:

  • 2021-05-17
  • 2021-10-28
  • 2021-07-29
  • 2022-12-23
  • 2022-12-23
  • 2021-06-17
  • 2022-12-23
猜你喜欢
  • 2021-07-12
  • 2022-01-17
  • 2021-12-05
  • 2022-12-23
  • 2022-03-07
  • 2022-02-08
  • 2022-03-03
相关资源
相似解决方案