zoukankan      html  css  js  c++  java
  • [原创]北大ACM POJ 1032题解

    [原创]北大ACM POJ 1032题解

    这道题找到规律了就很好写。

    题意就是求N1+N2+...+Nn=N. 使N1 ,N2...Nn都不相等且他们的乘积最大

    做法就是先求出以2为起始的最大连续自然数序列之和sum,使得sum的值不超过输入数n。
    然后分情况讨论:

    设此最大序列为2,3,...,i,则:

    1.若剩余值(n-sum)等于i,则最后输出序列为:3,4,...,i,i+2,即将原最大序列每项加1,再将最后剩余的一个1加到最后一项上。

    2.若剩余值(n-sum)小于i,则从序列的最大项i开始,从大到小依次将每项加1,直到剩余值用完。


    简单说明下此规律:
    首先说说连续,可以看到最后结果a[i]-a[i-1]<=2,也就是相邻两个数不能相差2以上,因为如果
    a[i]-a[i-1]=3,那么显然a[i]-1,a[i-1]+1也是满足要求的,且它们之间的乘积大于原来的,因此当相邻两个数相差2以上时,
    总可以找到它们之间的两个数使得结果是更优的。

    再来说说该序列必须以2或3开始,若序列第一项为5,则5=2+3,而2*3>5使得结果更优,对于大于5的第一项有类似结果。
    再考虑4为第一项,根据前面的第一条,那么第二项只能为5或6.对于4,5可以分解为2,3,4使得结果更优。而对于4,6可以分解为
    2,3,5使得结果更优
    。因此可以看到该序列不可能是以大于3为开始的。

    规律就是这样了,代码如下:

    Problem: 1032 User: absolute
    Memory: 204K Time: 32MS
    Language: C++ Result: Accepted

    #include
    <stdio.h>
    int main()
    {
    int n,j;
    scanf("%d",&n);
    int i=2;
    int sum=0;
    while(sum+i<=n)
    {
    sum += i;
    i++;
    }
    int diff = n-sum;
    if(diff==i-1)
    {
    for(j=3;j<i;j++)
    printf("%d ",j);
    printf("%d\n",j+1);
    }
    else
    {
    for(j=2;j<i-diff;j++)
    printf("%d ",j);
    for(j=i-diff;j<i;j++)
    printf("%d ",j+1);
    printf("\n");
    }
    return 0;
    }
  • 相关阅读:
    Axure chrome 安装及已损坏的解决方法
    Ubuntu16.04上使用git
    ubuntu初探
    nginx入门笔记
    更改element-UI按钮默认样式
    js深拷贝与浅拷贝的区别及实现
    安装mysql-python的遇到的问题
    facebook atc弱网环境搭建和踩坑总结
    验证码识别 Tesseract的简单使用和总结
    selenium 基础(一)
  • 原文地址:https://www.cnblogs.com/absolute8511/p/1649578.html
Copyright © 2011-2022 走看看