乘积最大(dfs+高精度)
题目描述
今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰 90 周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友 XZ 也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:
设有一个长度为 N的数字串,要求选手使用 K个乘号将它分成 K+1个部分,找出一种分法,使得这 K+1个部分的乘积能够为最大。
同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:
有一个数字串:312,当 N=3,K=1时会有以下两种分法:
(1)3×12=36
(2)31×2=62
这时,符合题目要求的结果是:31×2=62。
现在,请你帮助你的好朋友 XZ 设计一个程序,求得正确的答案。
输入格式
程序的输入共有两行:
第一行共有2各自然数N,K
第二行是一个长度为N的数字串
输出格式
结果显示在屏幕上,相对于输入,应输出所求得的最大乘积(一个自然数)。
输入样例
4 2
1231
输出样例
62
题解
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
using namespace std;
// 乘积最大
int n, k;
string ans = "1";
string s;
/*
long long 会爆
double wa点
所以自己写了个高精度 有点丑=.=
属于是暴力到底了 高精度+dfs剪枝
*/
// 以下皆为高精度
string _add(string x, string y) {
// 默认x比y长
string sum = "";
int jinwei = 0;
int x_index = x.size() - 1, y_index = y.size() - 1;
while (x_index >= 0) {
int temp = (x[x_index] - '0') + (y_index >= 0 ? y[y_index] - '0' : 0) + jinwei;
jinwei = temp / 10;
sum.insert(0, to_string(temp % 10));
x_index--, y_index--;
}
if (jinwei) sum.insert(0, to_string(jinwei));
return sum;
}
string add(string x, string y) {
string sum;
if (x.size() >= y.size()) sum = _add(x, y);
else sum = _add(y, x);
return sum;
}
string _mul(string x, string y, int y_con) {
// y为一位数
string sum = "";
int jinwei = 0, x_index = x.size() - 1;
while (x_index >= 0) {
int temp = (x[x_index] - '0') * (y[0] - '0') + jinwei;
jinwei = temp / 10;
sum.insert(0, to_string(temp % 10));
x_index--;
}
if (jinwei) sum.insert(0, to_string(jinwei));
for (int i = 1; i <= y_con; i++) sum.append("0");
return sum;
}
string mul(string x, string y) {
string sum = _mul(x, y.substr(y.size() - 1, 1), 0);
int y_index = y.size() - 2, con = 1;
while (y_index >= 0) {
sum = add(sum, _mul(x, y.substr(y_index, 1), con));
y_index--, con++;
}
return sum;
}
// 高精度数比较方法
bool compare(string x, string y) {
if (x.size() > y.size()) return 1;
else if (x.size() < y.size()) return 0;
else {
for (int i = 0; i < x.size(); i++) {
if (x[i] > y[i]) return 1;
else if (x[i] < y[i]) return 0;
else continue;
}
}
return 0;
}
void dfs(int index, string sum, int con) {
if (index >= s.size()) return;
if (con == k) {
sum = mul(sum, s.substr(index, s.size() - index));
if (compare(sum, ans)) ans = sum;
}
else {
int w = 1;
while (index + w < s.size()) {
dfs(index + w, mul(sum, s.substr(index, w)), con + 1);
w++;
}
}
}
int main() {
cin >> n >> k;
cin >> s;
dfs(0, "1", 0);
int flag = 0;
for (int i = 0; i < ans.size(); i++) {
if ((ans[i] - '0') != 0) flag = 1;
}
if (flag) cout << ans;
else cout << "0";
return 0;
}