最佳加法表达式

最佳加法表达式

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

解题思路:因为存在超大数,所以我用了一个数组表示一个数的方法,并且用全局数组ab来放置给定的数据,在digui(int a,int b,int c)函数中a代表当前进行ab数组中a下标,b代表还剩下的“+”,c代表上一个“+”右边的下标,我的递归函数就是已ab数组的长度和m<=n-1为边界,x代表在当前位的后面没有添置“+”,所以直接返回digui(a+1,b,c);y代表当前位后面添置了“+”,因此,y要加上前次“+”到此次“+”之间的数在加上digui(a+1,b-1,a+1)返回。(em.........表示我自己也没十分理清,能不能看懂就看你自己了。)
代码如下:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

//因为存在超大数 所以我用的数组来代替一个数 
vector<int> ab;	//记录输入数据的素组 
vector<int> notPass(52,1);//设置最大数 
void coutVector(vector<int> a);//输出数组所有元素就是相当于输出个数字 
vector<int> AddBigNum(vector<int> a,vector<int> b);//两个数组型的数字相加 
vector<int> digui(int a,int b,int c);//递归函数 
bool compare(vector<int> a,vector<int> b);//两个数组型的数字比较大小 
vector<vector<vector<vector<int> > > >judge;//递归的备忘录 
int main(){
	int m;
	while(cin>>m){
		string temp ;
		cin>>temp;
		//赋予空间获取数组 
		ab.resize(temp.size());
		judge.resize(temp.size());
		int i = 0,j=0,z=0;
		for(i = 0;i<temp.size();i++){
			ab[i] = temp[i] - 48;
			judge[i].resize(m+1);
			for(j=0;j<m+1;j++){
				judge[i][j].resize(temp.size());
			}
		}
		coutVector(digui(0,m,0));
		
		//清除数组空间 
		for(i = 0;i<temp.size();i++){
			for(j=0;j<m+1;j++){
				for(z=0;z<temp.size();z++){
					judge[i][j][z].clear();
				}
				judge[i][j].clear();
			}
			judge[i].clear();
		}
		judge.clear();
		ab.clear();
	}
	return 0;
}

//a表示当前到达数组ab的那个位置,b表示还剩下几个"+"
//c表示上一个"+"右边的位置 
vector<int> digui(int a,int b,int c){
	if(b == 0){//如果"+"已经给完,直接将后面的返回 
		 vector<int> d(ab.begin()+a,ab.end());
		 return judge[a][b][c] = d;
	}
	if(b > ab.size()-1-a || a >= ab.size()){//"+"大于等于剩余位数返回错误 
		return notPass;
	}
	if(judge[a][b][c].size() != 0){ //备忘录的用法 
		return judge[a][b][c];
	}
	vector<int> x = digui(a+1,b,c);	//x代表没有给当前位数后面"+"的值 
	vector<int> y(ab.begin()+c,ab.begin()+a+1);//y代表在当前位数后面给了 "+"
		y = AddBigNum(y,digui(a+1,b-1,a+1));//则y等于前一段加上后面的和 
	if(compare(x,y)){//比较大小,谁小返回谁 
		return  judge[a][b][c] = y;
	}else{
		return  judge[a][b][c] = x; 
	}
}

//比较大小,true表示a>=b,false则是a<b 
bool compare(vector<int> a,vector<int> b){
	if(a.size() > b.size()){
		return true;
	}else if(a.size() < b.size()){
		return false;
	}
	
	for(int i = 0; i<a.size() ;i++){
		if(a[i] > b[i]){
			return true;
		}else if(a[i] < b[i]){
			return false;
		}
	}
	return true;
}

//返回a+b的数组 
vector<int> AddBigNum(vector<int> a,vector<int> b){
	reverse(a.begin(),a.end());
	reverse(b.begin(),b.end());
	int i=0,j=0;
	vector<int> c;
	int temp = 0;
	while(i<a.size() && i<b.size()){
		temp += a[i]+b[i];
		c.push_back(temp%10);
		temp /= 10;
		i++;
	}
	while(i < a.size()){
		temp += a[i];
		c.push_back(temp%10);
		temp /= 10;
		i++;
	}
	while(i < b.size()){
		temp += b[i];
		c.push_back(temp%10);
		temp /= 10;
		i++;
	}
	if(temp != 0)
		c.push_back(temp);
	reverse(c.begin(),c.end());
	return c; 
}

//查BUG时为了方便写的打印数组 
void coutVector(vector<int> a){
	for(int i = 0;i<a.size();i++){
		cout<<a[i];
	}
	cout<<endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值