洛谷P1249题解

这篇具有很好参考价值的文章主要介绍了洛谷P1249题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、问题引出

最大乘积

题目描述

一个正整数一般可以分为几个互不相同的自然数的和,如 3 = 1 + 2 3=1+2 3=1+2 4 = 1 + 3 4=1+3 4=1+3 5 = 1 + 4 = 2 + 3 5=1+4=2+3 51+4=2+3 6 = 1 + 5 = 2 + 4 6=1+5=2+4 6=1+52+4

现在你的任务是将指定的正整数 n n n 分解成若干个互不相同的自然数的和,且使这些自然数的乘积最大。

输入格式

只一个正整数 n n n,( 3 ≤ n ≤ 10000 3 \leq n \leq 10000 3n10000)。

输出格式

第一行是分解方案,相邻的数之间用一个空格分开,并且按由小到大的顺序。

第二行是最大的乘积。

样例 #1

样例输入 #1

10

样例输出 #1

2 3 5
30

二、思路分析

本题要先用简单的数论和贪心找到最优解的组成方法,再用高精度乘法求积。文章来源地址https://www.toymoban.com/news/detail-448178.html

  • 以2004为例,由于把2004分拆成若干个互不相等的自然数的和的分法只有有限种,因而一定存在一种分法,使得这些自然数的乘积最大。
  • 若1作因数,则显然乘积不会最大。把2004分拆成若干个互不相等的自然数的和,因数个数越多,乘积越大。为了使因数个数尽可能地多,我们把2004分成2+3…+n直到和大于等于2004。
  • 若和比2004大1,则因数个数至少减少1个,为了使乘积最大,应去掉最小的2,并将最后一个数(最大)加上1。
  • 两个特例,“3”和“4”。这两个只能从拆成“1+2”和“1+3”。

三、正确代码

#include <iostream>
using namespace std;
string add(string s,string t)
{
    int len1=s.length();
    int len2=t.length();
    if(len1<len2)
    {
        for(int i=0;i<(len2-len1);i++)
        {
            s="0"+s;
        }
    }
    else
    {
        for(int i=0;i<(len1-len2);i++)
        {
            t="0"+t;
        }
    }
    int len=s.length();
    int r=0;
    string result;
    for(int i=len-1;i>=0;i--)
    {
        int sum=(int(s[i]-'0')+int(t[i]-'0')+r)%10;
        r=(int(s[i]-'0')+int(t[i]-'0')+r)/10;
        result=char(sum+'0')+result;
    }
    if(r!=0)
        result=char(r+'0')+result;
    return result;
}
string mul(string s,string t)
{
    if (s=="0" || t=="0")
    {
        return "0";
    }  
    int len1=s.length();
    int len2=t.length();
    string result;
    for(int i=len2-1;i>=0;i--)
    {
        string midResult;
        //获取乘数的值方便待会进行运算
        int x=t[i]-'0';
        for(int j=0;j<x;j++)
        {
            midResult=add(midResult,s);
        }
        //移位操作
        for (int j = 0; j < len2-1-i; j++)
        {
            midResult+="0";
        }
        result=add(result,midResult);
    }
    return result;
}
/**
 * @brief 
 * ans数组用于保存加数
 * s数组用于保存对应加数的字符串
 */
int ans[1001];
string s[1001];
int main()
{
    int n,c=1;
    string result="1";
    cin>>n;
    if (n<=4)
    {
        cout<<"1 "<<n<<endl;
        cout<<n;
        return 0;
    }
    for (int i = 2; i <= n; i++)
    {
        if (n>=i)
        {
            n-=i;
            ans[c++]=i;
            s[c-1]=to_string(i);
        }
        else
        {
            break;
        }
    }
    for (int i = c-1; i >= 1; i--)
    {
        if (n>0)
        {
            ans[i]++;
            s[i]=to_string(ans[i]);
            n--;
        }
    }
    if (n>0)
    {
        ans[c-1]++;
        s[c-1]=to_string(ans[c-1]);
    }
    for (int i = 1; i <= c-1; i++)
    {
        cout<<ans[i]<<" ";
        result=mul(result,s[i]);
    }
    cout<<endl;
    cout<<result;
}

到了这里,关于洛谷P1249题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【七】【C语言\动态规划】最大子数组和、环形子数组的最大和、乘积最大子数组,三道题目深度解析

    动态规划就像是解决问题的一种策略,它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题,并将每个小问题的解保存起来。这样,当我们需要解决原始问题的时候,我们就可以直接利用已经计算好的小问题的解,而不需要重

    2024年02月03日
    浏览(37)
  • 【洛谷 P4017】最大食物链计数 题解(深度优先搜索+动态规划+邻接表+记忆化搜索+剪枝)

    你知道食物链吗?Delia 生物考试的时候,数食物链条数的题目全都错了,因为她总是重复数了几条或漏掉了几条。于是她来就来求助你,然而你也不会啊!写一个程序来帮帮她吧。 给你一个食物网,你要求出这个食物网中最大食物链的数量。 (这里的“最大食物链”,指的

    2024年04月15日
    浏览(21)
  • 【洛谷 P1996】约瑟夫问题 题解(数组+模拟+循环)

    n n n 个人围成一圈,从第一个人开始报数,数到 m m m 的人出列,再由下一个人重新从 1 1 1 开始报数,数到 m m m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。 注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n − 1

    2024年02月07日
    浏览(25)
  • 【洛谷 P1106】删数问题 题解(贪心+字符串)

    键盘输入一个高精度的正整数 N N N (不超过 250 250 250 位),去掉其中任意 k k k 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 N N N 和 k k k ,寻找一种方案使得剩下的数字组成的新数最小。 输入两行正整数。 第一行输入一个高精度的正整数 n n

    2024年02月07日
    浏览(31)
  • 题解 # 二维矩阵最大矩形问题#

    小明有一张N*M的方格纸,且部分小方格中涂了颜色,部分小方格还是空白。 给出N (2Ns30)和M(2sMs30)的值,及每个小方格的状态((被涂了颜色小方格用数字1表示,空白小方格用数字0表示); 请帮助小明找出最大的矩形空白区域,并输出该矩形空白区域由多少个小方格组成。 例如

    2024年02月07日
    浏览(37)
  • 乘积最大子数组--动态规划

    乘积最大子数组 思路: 看到这个题的时候 要用DP的想法去做这道题 想到遍历到前面的值能不能为后面所用 假设有n个值 我们可以记录一下 第i个值的最大值是什么 怎么用到前面的值取判断 第i个值 可能正数 也可能是负数 如果是正数 那么我们乘以后面第i-1位的最大值 可以得

    2024年02月11日
    浏览(28)
  • 628. 三个数的最大乘积

    628. 三个数的最大乘积

    2024年02月15日
    浏览(20)
  • 动态规划 | 乘积最大

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

    2024年02月03日
    浏览(34)
  • Leetcode:238. 除自身以外数组的乘积【题解超详细】

    纯C语言实现(小白也能看明白) 题目 给你一个整数数组  nums ,返回  数组  answer  ,其中  answer[i]  等于  nums  中除  nums[i]  之外其余各元素的乘积  。 题目数据  保证  数组  nums 之中任意元素的全部前缀元素和后缀的乘积都在   32 位  整数范围内。 请 不要使用除

    2024年02月11日
    浏览(24)
  • leetcode 152. 乘积最大子数组

    题目链接:leetcode 152 给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。 测试用例的答案是一个 32-位 整数。 子数组 是数组的连续子序列。 1)示例 1: 输入: nums = [2,3,-2,4] 输出: 6 解释: 子数

    2024年02月03日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包