总时间限制:
1000ms
内存限制:
65536kB
描述

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

输入
有不超过15组数据
每组数据两行。第一行是整数m,表示有m个加号要放( 0<=m<=50)
第二行是若干个数字。数字总数n不超过50,且 m <= n-1
输出
对每组数据,输出最小加法表达式的值
样例输入
  1. 2
  2. 123456
  3. 1
  4. 123456
  5. 4
  6. 12345
样例输出
  1. 102
  2. 579
  3. 15
提示
要用到高精度计算,即用数组来存放long long 都装不下的大整数,并用模拟列竖式的办法进行大整数的加法。
来源
Guo Wei

题解:

本题难点在于利用数组实现高精度运算,模拟加减乘除
假设数字串的长度为 n,求将 m 个加号放入该字符串所形成的最小值
首先,分解子问题,规定最后一个加号的位置,假设将最后一个加号放在第 i 个数字后面,这时该问题就变成了在前i个数字中插入m - 1个加号所形成的最小值,加上第i + 1到第 n 个数字所组成的数的值( i 从 1 算起)
所以可以定义一个字符串加的函数add,利用引用型参数传递值。注意:字符串相加减,一定要注意高低位之分,可以在之前将字符串反转(可用STL中的 reverse(str.begin() , str.end()) 函数)
  1. void add(string &num1, string &num2, string &num3) {
  2. int l1 = num1.length();
  3. int l2 = num2.length();
  4. int c = ;//进位标志
  5. int maxl = Maxlen;
  6.  
  7. for(int i = ; i < maxl; i++) {
  8. int t;
  9. if(i < l1 && i < l2) {
  10. t = num1[i] + num2[i] - * '' + c;
  11. }
  12. else if(i < l1 && i >= l2) {
  13. t = num1[i] - '' + c;
  14. }
  15. else if(i >= l1 && i < l2) {
  16. t = num2[i] - '' + c;
  17. }
  18. else {
  19. break;
  20. }
  21. num3.append(, t % + '');
  22. c = t / ;
  23. }
  24. while (c)
  25. {
  26. num3.append(,c%+'');
  27. c /= ;
  28. }
  29. }
总代码:
  1. #include<iostream>
  2. using namespace std;
  3. #include<cstring>
  4. #include<string>
  5. #include<algorithm>
  6. #include<stdlib.h>
  7.  
  8. const int Maxlen = ;
  9. const string maxv = "";
  10. string ret[Maxlen][Maxlen];
  11. string num[Maxlen][Maxlen];
  12.  
  13. int cmp(string &num1, string &num2) {
  14. int l1 = num1.length();
  15. int l2 = num2.length();
  16. if(l1 != l2) {
  17. return (l1 - l2);
  18. }
  19. else {
  20. for(int i = l1 - ; i >= ; i--) {
  21. if(num1[i] != num2[i]) {
  22. return (num1[i] - num2[i]);
  23. }
  24. }
  25. return ;
  26. }
  27. }
  28.  
  29. void add(string &num1, string &num2, string &num3) {
  30. int l1 = num1.length();
  31. int l2 = num2.length();
  32. int c = ;//进位标志
  33. int maxl = Maxlen;
  34.  
  35. for(int i = ; i < maxl; i++) {
  36. int t;
  37. if(i < l1 && i < l2) {
  38. t = num1[i] + num2[i] - * '' + c;
  39. }
  40. else if(i < l1 && i >= l2) {
  41. t = num1[i] - '' + c;
  42. }
  43. else if(i >= l1 && i < l2) {
  44. t = num2[i] - '' + c;
  45. }
  46. else {
  47. break;
  48. }
  49. num3.append(, t % + '');
  50. c = t / ;
  51. }
  52. while (c)
  53. {
  54. num3.append(,c%+'');
  55. c /= ;
  56. }
  57. }
  58.  
  59. int main() {
  60. int m;
  61. string str;
  62. while(cin >> m >> str) {
  63. //加法从低位到高位相加,那么需要将字符串倒过来
  64. reverse(str.begin(), str.end());
  65. int n = str.length();
  66. for(int i = ; i < n; i++) {
  67. num[i + ][i + ] = str.substr(i, );
  68. }
  69. for(int i = ; i <= n; i++) {
  70. for(int j = i + ; j <= n; j++) {
  71. num[i][j] = str.substr(i - , j - i + );
  72. }
  73. }
  74.  
  75. for(int i = ; i <= n; i++) {//加号数目为0的时候
  76. ret[][i] = num[][i];
  77. }
  78. for(int i = ; i <= m; i++) {
  79. for(int j = ; j <= n; j++) {
  80. string minv = maxv;
  81. string temp;
  82. for(int k = i; k <= j - ; k++){//ret[m][n] = min(ret[m-1][i] + num[i+1][n]);
  83. temp.clear();
  84. add(ret[i - ][k], num[k + ][j], temp);
  85. if(cmp(temp, minv) < ) {
  86. minv = temp;
  87. }
  88. }
  89. ret[i][j] = minv;
  90. }
  91. }
  92. reverse(ret[m][n].begin(), ret[m][n].end());
  93. cout << ret[m][n] << endl;
  94. }
  95. return ;
  96. }

参考链接 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. VUE深入浅出(学习过程)

    VUE 2020年02月26日06:27:10 复习过Java8新特性之后开始学习VUE. 了解node了之后,来了解一下VUE.针对于学习VUE用什么开发工具这个问题上,我这里有vsCode和web ...

  2. 浅谈.NET Framework 与CLR

            承载公共语言运行时 (CLR) 的所有应用程序均需启动(或称“激活”)CLR 以运行托管代码.             通常,.NET Framework 应用程序在生成它的 CLR ...

  3. MySQL集群MGR架构for单主模式

    本文转载自: https://www.93bok.com MGR简介 MySQL Group Replication(简称MGR)是MySQL官方于2016年12月推出的一个全新的高可用与高扩展的解决 ...

  4. preload & prefetch

    原文地址在 我的笔记里,觉得还行就给个 star 吧:) 关于 preload 和 prefetch 早有耳闻,知道它们可以优化页面加载速度,然具体情况却了解不多.搜索了相关的资料后对其有了些认识,在 ...

  5. python之函数介绍

    # 函数 # 什么是函数: 能完成特定功能的工具,在Python中表示能完成特定功能的代码块.(函数定义) # 为什么要用函数 :①函数可以重复调用出来,效率高,而且维护成本低 ②使程序结构看起来清晰 ...

  6. Vue项目二、vue-cli2.x脚手架搭建build文件夹及config文件夹详解

    build文件夹下 build.js 'use strict' // js的严格模式 require('./check-versions')() // node和npm的版本检查 process.en ...

  7. layui表格数据渲染SpringBoot+Thymeleaf返回的数据时报错(Caused by: org.attoparser.ParseException: Could not parse as expression: ")

    layui table渲染数据时报错(Caused by: org.attoparser.ParseException: Could not parse as expression: ") ...

  8. 编译 ijg JPEG V8 库 GIF 库

    libjpeg-turbo-1.2.1太老了,不支持,从内存解压,这里编译支持 jpeg_mem_src 的 JPEG V9 wget http://www.ijg.org/files/jpegsrc ...

  9. 使用jquery实现动态时钟

    先导入jquery-1.7.2.min.js或其他版本文件 js部分 <script> $(function () { showTime(); //文档加载后.就开始显示时间 var se ...

  10. update join和delete join

    UPDATE ASET A.A2 = B.B2FROM BINNER JOIN AON A.A1 = B.B1WHERE B.B2 = "XXX" 上面的语句在SQL SERVER ...