首页 > 其他分享 >F. 乘积最大(题解)

F. 乘积最大(题解)

时间:2024-02-05 22:23:14浏览次数:19  
标签:乘积 temp int 题解 cf tempstr str string 最大

题目

今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰 90 周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友 XZ 也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:

设有一个长度为 的数字串,要求选手使用 个乘号将它分成 个部分,找出一种分法,使得这 个部分的乘积能够为最大。

同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:

有一个数字串:312,当n=3,k=1时会有以下两种分法:312=36;312=62;

这时,符合题目要求的结果是:31*2=62。

现在,请你帮助你的好朋友 XZ 设计一个程序,求得正确的答案。

输入

第一行共有2个自然数N,K(6≤N≤40,1≤K≤6)
第二行是一个长度为N的数字串。

输出

输出所求得的最大乘积(一个自然数)。

样例

4 2
1231

62

代码

点击查看代码
#include"bits/stdc++.h"
using namespace std;

int m,len;
string n;
string f[250][250],a[250][250];
string dp[250][250];
//dp[i][j]表示前i位拆成j段

//string的a.compare(b)函数比大小,在一些编译器上会返回“1”(a>b)“-1”(a<b)“0”(a=b),但是有一些编译器会返回正数、0、负数(就应为这个我调了一下午加半上午,恼了)
int comp(string x,string y)
{
    if(x.length()>y.length())return 1;
    else if(x.length()<y.length())return -1;
    else return x.compare(y);
}

//数据范围太大了,要打高精,这里完全是string的高精乘和加,因为我觉得转来转去太麻烦了干脆直接到最后都用string输出
string add(string str1,string str2)
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    if(len1<len2)
    {
        for(int i=1;i<=len2-len1;i++)
           str1="0"+str1;
    }
    else
    {
        for(int i=1;i<=len1-len2;i++)
           str2="0"+str2;
    }
    len1=str1.length();
    int cf=0;
    int temp=0;
    for(int i=len1-1;i>=0;i--)
    {
        temp=str1[i]-'0'+str2[i]-'0'+cf;
        cf=temp/10;
        temp%=10;
        str=char(temp+'0')+str;
    }
    if(cf!=0)  str=char(cf+'0')+str;
    return str;
}

string cheng(string str1,string str2)
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    string tempstr;
    for(int i=len2-1;i>=0;i--)
    {
        tempstr="";
        int temp=str2[i]-'0';
        int t=0;
        int cf=0;
        if(temp!=0)
        {
            for(int j=1;j<=len2-1-i;j++)
              tempstr+="0";
            for(int j=len1-1;j>=0;j--)
            {
                t=(temp*(str1[j]-'0')+cf)%10;
                cf=(temp*(str1[j]-'0')+cf)/10;
                tempstr=char(t+'0')+tempstr;
            }
            if(cf!=0) tempstr=char(cf+'0')+tempstr;
        }
        str=add(str,tempstr);
    }
    str.erase(0,str.find_first_not_of('0'));
    return str;
}

int main()
{
    cin >>len>>m>>n;
    
//预处理:把数字拆开
    for (int i=1;i<=249;i++) 
    {
        for (int j=1;j<=249; j++) 
        {
            dp[i][j]="0";
        }
    }
//m表示乘号个数,m+1表示分成几段,和dp的照应
    m+=1;
    for(int i=0;i<len;i++)
    {
        for(int j=i;j<len;j++)
        {
            f[i+1][j+1]=n.substr(i,j-i+1);
        }
    }
//初始化
    for(int i=0;i<=len;i++)
    {
        for(int j=0;j<=len;j++)
        {
            dp[i][j]="0";
        }
    }
    dp[0][0]="1";//dp为string类型,所以赋值为字符'1'
    for(int i=1;i<=len;i++)
    {
        int ki=min(i,m);
        for(int j=1;j<=ki;j++)
        {
            for(int k=1;k<=i;k++)
            {
                if(comp(cheng(dp[k-1][j-1],f[k][i]),dp[i][j])>0)//一定要写>0,下面会写为啥
                {
                    dp[i][j]=cheng(dp[k-1][j-1],f[k][i]);
                }
            }
        }
    }
    cout <<dp[len][m];

    return 0;
}

写这个题解的原因

主要是因为昨天下午写出来以后,没A,23-PeppaEvenPig就给我改,也没过,偶然间发现在v
scode上和oi上跑出来的结果不一样,在vscode上A了,所以就一直调,然后再acwing上跑,结果输出还和oi上不一样,就很无语,最后经过铸(这字念tao,别管为啥)哥的不懈努力,发现compare的问题,就离谱了,然后改了之后就A了,浪费我半天的时间,恼了。(手动愤怒)

标签:乘积,temp,int,题解,cf,tempstr,str,string,最大
From: https://www.cnblogs.com/wangqa080211/p/18008917

相关文章

  • [ARC135D] Add to Square 题解
    题目链接点击打开链接题目解法很牛的题!!!先考虑一步很牛的转化:把矩阵黑白染色,且\(i+j\)为奇数的位置的值取反,每次操作变为左上右下\(+v\),左下右上\(-v\)这样有啥好处?操作不会使行和列的和改变考虑答案的下界显然是:\(\max\{\)行的绝对值之和,列的绝对值之和\(\}\)这里给出......
  • luogu2647题解
    首先这道题没有规定选几个。一开始我以为是全选,然后想了个贪心才发现看错了。那我们先来假设选\(m\)个。这个题的每个物品都会影响后面物品的收益,不好看。由于每个物品\(i\)对后选的其他物品减少的收益都是\(R_i\),因此我们在保证总价值不变的情况下转化一下,把该物品的价......
  • P10125 「Daily OI Round 3」Simple 题解
    题目传送门简单模拟,主要考察字符串。首先输入一个char类型的数组,然后直接遍历每一位是否为Acoipp或Svpoll即可。//Simple//codeby:cq_irritater//time:2024/02/04#include<bits/stdc++.h>usingnamespacestd;chara[10];intmain(){//freopen("c......
  • 中文数字的应用及其问题解决之道
    中文数字,也称汉字数字,是中文语言中表示数字的一种方式。它们不仅有着悠久的历史和文化背景,还在日常生活中发挥着重要的作用。本文将探讨中文数字的应用领域,并介绍它们如何解决实际问题。中文数字-阿拉伯数字转换|一个覆盖广泛主题工具的高效在线平台(amd794.com)https:/......
  • 代码随想录算法训练营第十三天|239. 滑动窗口最大值 347.前 K 个高频元素 总结
    239.滑动窗口最大值题目链接:239.滑动窗口最大值-力扣(LeetCode)给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。思路:首先在不考虑......
  • java lambda 求分组内最大值
    可以使用lambda表达式,比较方便,这里主要想说下思路问题,之前一个时受到数据库的影响,一个是对api理解程度不够的原因,实现方式见方式一;后来有种恍然大悟的感觉,改成了方式二的实现;方式一:先分组,组内过滤每一条数据Map<String,List<UserLog>>collect=list.stream().collect(Collec......
  • P2367 语文成绩 题解
    语文成绩题目背景语文考试结束了,成绩还是一如既往地有问题。题目描述语文老师总是写错成绩,所以当她修改成绩的时候,总是累得不行。她总是要一遍遍地给某些同学增加分数,又要注意最低分是多少。你能帮帮她吗?输入格式第一行有两个整数\(n\),\(p\),代表学生数与增加分数的次数。......
  • 题解 ARC171D【Rolling Hash】
    来补题了。昨天赛时想法是对的,代码写错了,没调过太可惜了。显然\(P>n\)时必定有解。设前缀\([1,i]\)的哈希值为\(s_i\),显然\([l,r]\)的哈希值不为\(0\)的充要条件是\(s_{l-1}\nes_r\)。建立一个点的编号为\(0\simn\)的图,对于每个输入的区间\([l,r]\),连接一条边......
  • 【洛谷 P2437】蜜蜂路线 题解(递归+记忆化搜索+高精度)
    蜜蜂路线题目描述一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房开始爬到蜂房,,有多少种爬行路线?(备注:题面有误,右上角应为)输入格式输入的值输出格式爬行有多少种路线样例#1样例输入#1114样例输出#1377提示对于100%的......
  • 题解 ARC171C【Swap on Tree】
    每棵子树内只可能有至多一个外来的数,且外来的数是多少并不影响方案数,因此考虑设\(f_{u,i,0/1}\)表示考虑以\(u\)为根的子树,与\(u\)相连的所有边中断了\(i\)条,且\(u\)与其父亲之间的边有没有断的方案数。设\(g_{u,c}=\sumf_{u,i,c}\)。每个节点的初始状态是\(f_{u,0,......