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

题解:

本题难点在于利用数组实现高精度运算,模拟加减乘除
假设数字串的长度为 n,求将 m 个加号放入该字符串所形成的最小值
首先,分解子问题,规定最后一个加号的位置,假设将最后一个加号放在第 i 个数字后面,这时该问题就变成了在前i个数字中插入m - 1个加号所形成的最小值,加上第i + 1到第 n 个数字所组成的数的值( i 从 1 算起)
所以可以定义一个字符串加的函数add,利用引用型参数传递值。注意:字符串相加减,一定要注意高低位之分,可以在之前将字符串反转(可用STL中的 reverse(str.begin() , str.end()) 函数)
 void add(string &num1, string &num2, string &num3) {
int l1 = num1.length();
int l2 = num2.length();
int c = ;//进位标志
int maxl = Maxlen; for(int i = ; i < maxl; i++) {
int t;
if(i < l1 && i < l2) {
t = num1[i] + num2[i] - * '' + c;
}
else if(i < l1 && i >= l2) {
t = num1[i] - '' + c;
}
else if(i >= l1 && i < l2) {
t = num2[i] - '' + c;
}
else {
break;
}
num3.append(, t % + '');
c = t / ;
}
while (c)
{
num3.append(,c%+'');
c /= ;
}
}
总代码:
 #include<iostream>
using namespace std;
#include<cstring>
#include<string>
#include<algorithm>
#include<stdlib.h> const int Maxlen = ;
const string maxv = "";
string ret[Maxlen][Maxlen];
string num[Maxlen][Maxlen]; int cmp(string &num1, string &num2) {
int l1 = num1.length();
int l2 = num2.length();
if(l1 != l2) {
return (l1 - l2);
}
else {
for(int i = l1 - ; i >= ; i--) {
if(num1[i] != num2[i]) {
return (num1[i] - num2[i]);
}
}
return ;
}
} void add(string &num1, string &num2, string &num3) {
int l1 = num1.length();
int l2 = num2.length();
int c = ;//进位标志
int maxl = Maxlen; for(int i = ; i < maxl; i++) {
int t;
if(i < l1 && i < l2) {
t = num1[i] + num2[i] - * '' + c;
}
else if(i < l1 && i >= l2) {
t = num1[i] - '' + c;
}
else if(i >= l1 && i < l2) {
t = num2[i] - '' + c;
}
else {
break;
}
num3.append(, t % + '');
c = t / ;
}
while (c)
{
num3.append(,c%+'');
c /= ;
}
} int main() {
int m;
string str;
while(cin >> m >> str) {
//加法从低位到高位相加,那么需要将字符串倒过来
reverse(str.begin(), str.end());
int n = str.length();
for(int i = ; i < n; i++) {
num[i + ][i + ] = str.substr(i, );
}
for(int i = ; i <= n; i++) {
for(int j = i + ; j <= n; j++) {
num[i][j] = str.substr(i - , j - i + );
}
} for(int i = ; i <= n; i++) {//加号数目为0的时候
ret[][i] = num[][i];
}
for(int i = ; i <= m; i++) {
for(int j = ; j <= n; j++) {
string minv = maxv;
string temp;
for(int k = i; k <= j - ; k++){//ret[m][n] = min(ret[m-1][i] + num[i+1][n]);
temp.clear();
add(ret[i - ][k], num[k + ][j], temp);
if(cmp(temp, minv) < ) {
minv = temp;
}
}
ret[i][j] = minv;
}
}
reverse(ret[m][n].begin(), ret[m][n].end());
cout << ret[m][n] << endl;
}
return ;
}

参考链接 https://blog.csdn.net/qq_35049196/article/details/58247829

【动态规划】最佳加法表达式(百练oj4152)的更多相关文章

  1. 【OpenJ_Bailian - 4152 】最佳加法表达式(动态规划)

    最佳加法表达式 Descriptions: 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值.例如,在1234中摆放1个加号,最好的摆 ...

  2. dp 动规 最佳加法表达式

    最佳加法表达式 有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中,值最小的那个表达式的值是多少 解题思路 假定数字串长度是n,添完加号后,表达式的最后一个加号 ...

  3. 百练4152:最佳加法表达式(dp+高精度)

    描述 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值.例如,在1234中摆放1个加号,最好的摆法就是12+34,和为36 输入有不超 ...

  4. OpenJudge 4152 最佳加法表达式

    总时间限制: 1000ms 内存限制: 65536kB 描述 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值.例如,在1234中摆放 ...

  5. 递推,动态规划(DP),字符串处理,最佳加法表达式

    看了一些资料,竟然发现连百度文库也有错误的地方,在这里吐槽一下题目大意:http://wenku.baidu.com/link?url=DrUNNm19IqpPNZjKPX4Jg6shJiK_Nho6 ...

  6. 最佳加法表达式(dp)

    题目描述: 有一个由1..9组成的数字串.问如果将m个加 号插入到这个数字串中,在各种可能形成的 表达式中,值最小的那个表达式的值是多少 (本题只能用于整数) 解题思路: 假定数字串长度是n,添完加号 ...

  7. OpenJ_Bailian - 4152 最佳加法表达式 dp

    http://bailian.openjudge.cn/practice/4152?lang=en_US 题解 :dp[i][j]代表前i个字符加j个加号可以得到的最小值,于是dp[i+k[j+1]可 ...

  8. ACM/ICPC 之 递归(POJ2663-完全覆盖+POJ1057(百练2775)-旧式文件结构图)

    POJ2663-完全覆盖 题解见首注释 //简单递推-三个米诺牌(3*2)为一个单位打草稿得出规律 //题意-3*n块方格能被1*2的米诺牌以多少种情况完全覆盖 //Memory 132K Time: ...

  9. 百练6255-单词反转-2016正式B题

    百练 / 2016计算机学科夏令营上机考试 已经结束 题目 排名 状态 统计 提问   B:单词翻转 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一个 ...

随机推荐

  1. win10下LoadRunner12 下载安装图文教程

    1.下载安装包: 链接:https://pan.baidu.com/s/1hiGC9FjfKOFRWHVfMAHaeg 提取码:sr8x 如下图所示,咱们直接安装社区版“HP_LoadRunner_1 ...

  2. [讨论] 平台建设,我们从架构中去掉kafka?

    目       录 1.      概述... 2 2.      原有结构(带kafka)... 2 3.      改造后的结构(去掉kafka)... 3 4.      对比... 4 1.  ...

  3. 修改gridfilters.js源码,往后台多传递一个参数,并设置NumericFilter、StringFilter默认提示信息

    创作不易,转载请注明出处!!! 效果 修改:ext-extend.js源码 在最后面添加3行,重写方法 代码拷贝区 Ext.override(Ext.ux.grid.GridFilters, { me ...

  4. javascript设计模式--策略模式

    javascript策略模式总结 1.什么是策略模式? 策略模式的定义是:定义一系列的算法,把他们独立封装起来,并且可以相互替换. 例如我们需要写一段代码来计算员工的奖金.当绩效为a时,奖金为工资的5 ...

  5. 原生js写一个无缝轮播图插件(支持vue)

    轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端.因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使 ...

  6. AOP和spring AOP学习记录

    AOP基本概念的理解 面向切面AOP主要是在编译期或运行时,对程序进行织入,实现代理, 对原代码毫无侵入性,不破坏主要业务逻辑,减少程序的耦合度. 主要应用范围: 日志记录,性能统计,安全控制,事务处 ...

  7. Windows环境下docker的安装与配置

    Docker是一种容器技术,可以在操作系统中隔离出若干个独立的程序运行环境,这些环境既可以共享宿主机的资源,另一方面他们之间相互独立,互不影响,也不会对宿主机的环境产生影响.与虚拟化技术不同的是,Do ...

  8. oracle 10g 搭建备库以及一次DG GAP的处理情况

    1.主庫全庫備份rman target/rman> backup database format '/backup/fullbak/fullbak_%U';2.用scp傳到備庫,最好是rman目 ...

  9. 如何优雅的使用AbpSettings

    在Abp中配置虽然使用方便,但是每个配置要先定义key,要去provider中定义,再最后使用key从ISetting中获取还是挺麻烦的一件事, 最主要是获取修改的时候,比如,修改用户配置,是从获取一 ...

  10. ES6中的Promise使用总结

    One.什么是Promise? Promise是异步编程的解决方案,而它本身也就是一个构造函数,比传统的异步解决[回调函数]和[事件]更合理,更强大. Two.Promise有何作用? 作用:解决回调 ...