P1018 乘积最大题解

P1018 乘积最大

题意:有一个字符串s(|s|<=40),给k(k<=6)个乘号,问怎样组合得到的数字最大。

解法:这题不难!只是太复杂了!40位的数据的话,只能用高精度了,做法是dp,先预处理出qj[i][j] (i≤j)表示s字符串位置在i-j的子串,dp[i][j]表示以i为结尾用了j个乘号得到的最大数字,那么转移方程就是 d p [ i ] [ j ] = m a x ( d p [ i ] [ j ] , d p [ x ] [ j − 1 ] ∗ q j [ x + 1 ] [ i ] ) dp[i][j]=max(dp[i][j], dp[x][j-1]*qj[x+1][i]) dp[i][j]=max(dp[i][j],dp[x][j1]qj[x+1][i]),注意一下边界问题就可。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int ne[4][2] = {
    
    1, 0, 0, 1, -1, 0, 0, -1};
const int N = 50;
int n, k;
string s;

string max(string a, string b) {
    
    
	if(a.size() != b.size()) return a.size() < b.size() ? b : a; 
	return a < b ? b : a; 
}

//高精度加法 
string add(string a, string b) {
    
    
	string res = "", r = "";
	int jw = 0, l1 = a.size(), l2 = b.size();
	int p1 = l1-1, p2 = l2-1, mid;
	while(p1 >= 0 && p2 >= 0) {
    
    
		mid = a[p1--]-'0'+b[p2--]-'0'+jw; jw = 0;
		r = (mid%10)+'0';
		res.insert(0, r);
		if(mid >= 10) jw = mid/10;
	}
	while(p1 >= 0) {
    
    
		mid = a[p1--]-'0'+jw; jw = 0;
		r = (mid%10)+'0';
		res.insert(0, r);
		if(mid >= 10) jw = mid/10;
	}
	while(p2 >= 0) {
    
    
		mid = b[p2--]-'0'+jw; jw = 0;
		r = (mid%10)+'0';
		res.insert(0, r);
		if(mid >= 10) jw = mid/10;
	}
	if(jw) res.insert(0, "1");
	return res;
}

//高精度乘法
string mul(string a, string b) {
    
    
	string res = "", r1 = "", r;
	int jw = 0, l1 = a.size(), l2 = b.size();
	int mid, num_0 = 0;
	for(int i = l2-1; i >= 0; --i) {
    
    
		r1 = "";
		for(int j = l1-1; j >= 0; --j) {
    
    
			mid = (b[i]-'0')*(a[j]-'0')+jw; jw = 0;
			r = (mid%10) + '0';
			r1.insert(0, r);
			if(mid >= 10) jw = mid / 10;
		}
		if(jw) {
    
     r = jw + '0', r1.insert(0, r); jw = 0; }
		for(int j = 0; j < num_0; ++j) r1.append("0");
		++num_0;
		res = add(res, r1); 
	}
	return res;
} 

string qj[N][N], dp[N][N];
int main() {
    
    
	cin >> n >> k >> s;
	int len = s.size();
	for(int i = 0; i < len; ++i) for(int j = i; j < len; ++j) 
		qj[i][j] = s.substr(i, j-i+1);
	//预处理
	for(int i = 0; i < len; ++i) {
    
    
		dp[i][0] = qj[0][i];
		for(int j = 1; j <= k; ++j) dp[i][j] = "0";
	}
	//dp!
	for(int i = 0; i < len; ++i) {
    
    
		for(int j = 1; j <= k; ++j) {
    
    
			for(int x = j-1; x < len; ++x) {
    
    
				dp[i][j] = max(dp[i][j], mul(dp[x][j-1], qj[x+1][i]));
			}
		}
	}
	cout << dp[len-1][k] << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43408978/article/details/109036488
今日推荐