OpenJudge 4152 最佳加法表达式
总时间限制: 1000ms 内存限制: 65536kB
描述
给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值。例如,在1234中摆放1个加号,最好的摆法就是12+34,和为36
输入
有不超过15组数据
每组数据两行。第一行是整数m,表示有m个加号要放( 0<=m<=50)
第二行是若干个数字。数字总数n不超过50,且 m <= n-1
输出
对每组数据,输出最小加法表达式的值
样例输入
样例输出
提示
要用到高精度计算,即用数组来存放long long 都装不下的大整数,并用模拟列竖式的办法进行大整数的加法。
解题思路
主要难点在高精度计算,以下提供两种解法,码着日后研究。
AC代码一
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
struct BigInt
{
int num[];
int len;
BigInt operator+(const BigInt & n) { //重载+,使得 a + b在 a,b都是 BigInt变量的时候能成立
int ml = max(len,n.len);
int carry = ; //进位
BigInt result;
for(int i = ;i < ml; ++i) {
result.num[i] = num[i] + n.num[i] + carry;
if( result.num[i] >= ) {
carry = ;
result.num[i] -= ;
}
else
carry = ;
}
if ( carry == ) {
result.len = ml + ;
result.num[ml] = ;
}
else
result.len = ml;
return result;
}
bool operator<(const BigInt & n) {
if( len > n.len )
return false;
else if( len < n.len)
return true;
else {
for(int i = len -; i >= ; -- i) {
if( num[i] < n.num[i])
return true;
else if( num[i] > n.num[i])
return false;
}
return false;
}
}
BigInt() {
len = ;
memset(num,,sizeof(num));
}
BigInt(const char * n,int L) { //由长度为L的char数组构造大整数。n里面的元素取值范围从 1-9。
memset(num,,sizeof(num));
len = L;
for(int i = ; n[i]; ++i)
num[len-i-] = n[i] - '';
}
};
ostream & operator <<(ostream & o,const BigInt & n)
{ for(int i = n.len - ;i >= ; --i)
o << n.num[i];
return o;
}
const int MAXN = ;
char a[MAXN];
BigInt Num[MAXN][MAXN];//Num[i][j]表示从第i个数字到第j个数字所构成的整数
BigInt V[MAXN][MAXN]; //V[i][j]表示i个加号放到前j个数字中间,所能得到的最佳表达式的值。
int main()
{
int m,n;
BigInt inf; //无穷大
inf.num[MAXN-] = ;
inf.len = MAXN-; while(cin >> m ) {
cin >> a+;
n = strlen(a+);
for(int i = ;i <= n; ++i)
for(int j = i;j<= n; ++j) {
Num[i][j] = BigInt(a+i,j-i+);
}
for(int j = ; j <= n; ++j) {
V[][j] = BigInt(a+,j);
} for(int i = ;i <= m; ++i) {
for(int j = ; j <= n; ++j) {
if( j - < i)
V[i][j] = inf;
else {
BigInt tmpMin = inf;
for(int k = i; k < j; ++k) {
BigInt tmp = V[i-][k] + Num[k+][j];
if (tmp < tmpMin)
tmpMin = tmp;
}
V[i][j] = tmpMin;
}
}
}
cout << V[m][n] << endl;
}
return ;
}
AC代码二
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <vector>
#include <stack>
#define mp make_pair
//#define P make_pair
#define MIN(a,b) (a>b?b:a)
//#define MAX(a,b) (a>b?a:b)
typedef long long ll;
typedef unsigned long long ull;
const int MAX=1e2+;
const int INF=1e8+;
using namespace std;
//const int MOD=1e9+7;
typedef pair<ll,int> pii;
const double eps=0.00000001; string add(string x,string y)
{
string re;
int jin=;
for(int i=x.length()-,j=y.length()-;i>=||j>=;i--,j--)
{
re=" "+re;
re[]=(i>=?x[i]-'':)+(j>=?y[j]-'':)+jin;
if(re[]>=)
jin=,re[]=(re[]%)+'';
else
jin=,re[]=re[]+'';
}
if(jin)
re=''+re;
return re;
}
string mins(string x,string y)
{
if(x.length()<y.length())
return x;
else if(y.length()<x.length())
return y;
else return x<y?x:y;
}
int m;
string x;
string dp[][];
int main()
{
while(~scanf("%d",&m))
{
cin>>x;
int len=x.length();
x=" "+x;
for(int i=;i<=len;i++)
dp[i][]=x.substr(,i);
for(int j=;j<=m;j++)
for(int i=j+;i<=len;i++)
for(int s=j;s<i;s++)
{
if(s==j)
dp[i][j]=add(dp[s][j-],x.substr(s+,i-s));
else
dp[i][j]=mins(dp[i][j],add(dp[s][j-],x.substr(s+,i-s)));
}
cout<<dp[len][m]<<"\n";
}
}
参考网址
https://blog.csdn.net/qq_43472263/article/details/88652211
https://www.cnblogs.com/huashanqingzhu/p/8097787.html
OpenJudge 4152 最佳加法表达式的更多相关文章
- 百练4152:最佳加法表达式(dp+高精度)
描述 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值.例如,在1234中摆放1个加号,最好的摆法就是12+34,和为36 输入有不超 ...
- OpenJ_Bailian - 4152 最佳加法表达式 dp
http://bailian.openjudge.cn/practice/4152?lang=en_US 题解 :dp[i][j]代表前i个字符加j个加号可以得到的最小值,于是dp[i+k[j+1]可 ...
- 【OpenJ_Bailian - 4152 】最佳加法表达式(动态规划)
最佳加法表达式 Descriptions: 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值.例如,在1234中摆放1个加号,最好的摆 ...
- dp 动规 最佳加法表达式
最佳加法表达式 有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中,值最小的那个表达式的值是多少 解题思路 假定数字串长度是n,添完加号后,表达式的最后一个加号 ...
- 【动态规划】最佳加法表达式(百练oj4152)
总时间限制: 1000ms 内存限制: 65536kB 描述 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值.例如,在1234中摆放 ...
- 最佳加法表达式(dp)
题目描述: 有一个由1..9组成的数字串.问如果将m个加 号插入到这个数字串中,在各种可能形成的 表达式中,值最小的那个表达式的值是多少 (本题只能用于整数) 解题思路: 假定数字串长度是n,添完加号 ...
- 递推,动态规划(DP),字符串处理,最佳加法表达式
看了一些资料,竟然发现连百度文库也有错误的地方,在这里吐槽一下题目大意:http://wenku.baidu.com/link?url=DrUNNm19IqpPNZjKPX4Jg6shJiK_Nho6 ...
- java源码——0~9十个数字不重复地使用使加法表达式成立
这个问题是在我写个的几个博客里较为复杂的一个.首先,先看看整个问题的表述. 星号表示0~9的一个数字,而且不允许重复,使得下面的加法表达式成立.输出所有结果. ※ ※ ※ ※ ※ + 2 ...
- OpenJudge 2694 逆波兰表达式
1.链接地址: http://bailian.openjudge.cn/practice/2694/ 2.题目: 总时间限制: 1000ms 内存限制: 65536kB 描述 逆波兰表达式是一种把运算 ...
随机推荐
- 项目Alpha冲刺 8
作业描述 课程: 软件工程1916|W(福州大学) 作业要求: 项目Alpha冲刺(团队) 团队名称: 火鸡堂 作业目标: 介绍第8天冲刺的项目进展.问题困难和心得体会 1.团队信息 队名:火鸡堂 队 ...
- 编程小白入门分享四:Vue的安装及使用快速入门
一.VUE简介 vue是一个JavaMVVM库,是一套用于构建用户界面的渐进式框架,是初创项目的首选前端框架.它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计.它是轻量级的,它有很多独立 ...
- luoguP2768: 珍珠项链(矩阵乘法优化DP)
题意:有K种珍珠,每种N颗,求长度为1~N的项链,包含K种珍珠的项链种类数.N<=1e9, K<=30; 思路:矩阵快速幂,加个1累加前缀和即可. #include<bits/std ...
- npm中的学习课程
我也不知道叫什么名字好 进入 https://nodeschool.io/zh-cn/,你能够看到许多课程. 这些课程大多面向零基础的,非常有趣(类似于许多关卡的小游戏). 快速开始 首先,确定你的电 ...
- Oracle iops测试
DECLARE lat INTEGER; iops INTEGER; mbps INTEGER;BEGIN DBMS_RESOURCE_MANAGER.CALIBRATE_IO(4, 10, ...
- UFUN函数 UF_ATTR函数(UF_ATTR_assign ,UF_ATTR_read_value )
UF_initialize(); tag_t ; ]="零件名称"; UF_ATTR_value_t value; value.type=UF_ATTR_string; value ...
- vue+elementUI完成注册及登陆
1. vue怎么引入和配置使用element-ui框架 1.1 使用vue-cli脚手架工具创建一个vue项目 vue init webpack pro01 1.2 npm安装elementUI cd ...
- Tomcat启动服务报错:Unknown version string [4.0]. Default version will be used.
Tomcat.jdk.web.xml 对应关系: 版本对应错误,更换便可.(版本往下兼容) web.xml——version2.2——JDK1.1——Tomcat3.3 web.xml——versio ...
- xamarin/xamarin.forms 在锁屏电源唤醒时保持后台运行
PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的. SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯 SCRE ...
- 【POJ1068】Parencodings
题目传送门 本题知识点:模拟 这是一道恐怖的括号题.题意稍微理解以下还是可以的. 我们针对样例来理解一下 S.P.W 到底是什么意思: S:( ( ( ( ) ( ) ( ) ) ) ) P: \(P ...