贪心算法最优分解问题



最优分解问题

设n是一个正整数,现在要求将n分解为若干个互不相同的自然数的和,使这些自然数的乘积最大。
输入 10
输出 30
(被分解为5 2 3)

分析:

1、若a+b等于一个常数,则|a-b|越小,a*b就越大。要使得加数互不相同,又尽可能集中,那加数只能是连续的自然数了。
2、一个数能分解,分解后乘积会比之前更大。如6,分成2和4,乘积8>6



3、如图,按理说,下一步再从diff中分解出6,但是diff<p[3],无法分解。要把diff均匀(每次加1)地加到前面每一项,并且后项优先原则。

#include<stdio.h>
int main(){
    int n;           //被分解的数 
    printf("n的值:\n");
    scanf("%d",&n);
    int p[n/2];  //接收n分解成的自然数
    int i,j,num=0;
    int s=1;
    
    p[0]=2;
    int diff=n-2;
    for(i=0;i<n/2;i++){  
        p[i+1]=p[i]+1;
        diff-=p[i+1];
        if(diff<=p[i+1]){
            break;
        }
    }
    
    num=i+2;//n=15,i=2时diff<p[i+1],退出循环,i仍然为2,但实际呢,
            //有p[0],p[1],p[2],p[3]四个元素,所以再加2 ,得到数组的个数 
            
    while(diff!=0){
        //此时diff为1,还需要把它加到前面的各个数上 
        //原则:后项优先,所以应该给p[3]加上 
        j=num;
        p[j-1]++;
        diff--;
        j--;
        if(j==0)    //因为循环赋值
            j=num;
    } 
    
    printf("%d被分解为:\n",n);
    for(i=0;i<num;i++)
     {
        s*=p[i];
        printf("%d\t",p[i]);
     }
     printf("\n乘积最大为:");
     
     printf("%d\n",s);
     return 0;
}
运行截图

推荐阅读更多精彩内容