乘积最大(dfs+高精度)

乘积最大(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值