本题来源:MOOC郭炜老师算法学习练习
最佳加法表达式
问题重述
给定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 都装不下的大整数,并用模拟列竖式的办法进行大整数的加法。
思路分析:
还是比较规范的动态规划算法题,我们设定当前状态是 ans[n][m] 表示前 n 个数里放入 m 个加号后所能得到的最小值。状态转移就是 ans[n][m]=min(ans[n][m],ans[i][m-1]+temp) ,其中 ans[n][m] 表示我们要求的当前状态, ans[i][m-1] 表示要从哪些状态转移过来,i 的取值有多种我们要保证前 i 个数能放下 m-1 个加号且 i 之后还要有数即 temp 我们要计算每一种可能所以加号能放的位置要全部遍历。但因为数据太大我们要用到高精度算法,这里的运算我们都要重新定义我们需要的运算有比较大小和相加运算,一开始我用数组模拟大数的相加和比较后来发现过于麻烦(也是因为我水平不够),后来想到字符串的方法较多便又用了字符串模拟,发现较简洁。
C++代码:
#include<iostream>
#include<cstring>
using namespace std;
string s;//表示每次要处理的大数
string ans[52][52];//定义一个答案数组存储前n个数里放入m个加号后所能得到的最小值
void init()//初始化答案数组
{
for(int i=0;i<52;i++)
for(int j=0;j<52;j++)
ans[i][j]="";
}
string mins(string a,string b)//高精度字符串模拟比较大小
{
if(<

本文探讨了在一组数字间放置加号以形成最小加法表达式的算法问题。通过动态规划方法,结合高精度计算技巧,实现了对大量数据的有效处理。文章详细介绍了使用字符串模拟进行大数比较和加法的过程。
最低0.47元/天 解锁文章
1068

被折叠的 条评论
为什么被折叠?



