• HDU 1028 Ignatius and the Princess III伊格和公主III(AC代码)母函数


    题意:

      输入一个数n,求组合成此数字可以有多少种方法,每一方法是不记录排列顺序的。用来组成的数字可以有1、2、3....n。比如n个1组成了n,一个n也组成n。这就算两种。1=1,2=1+1=2,3=3=1+2=1+1+1,而1+2和2+1只能算一种。n最大为120。

    思路:关于母函数的原理不讲了。讲怎么实现几个括号相乘。

    思路:

    我们要算的n是等于120,把其简化为5,就是说设n最大为5,道理一样的。5一共有7种方法对吗!自己手写吧。

    如果想要得出结果,那么一共有5个括号要相乘,分别如下:

    为什么是5个括号?

    第1个括号:最多可由5个1组成。

    第2个括号:最多只能有两个2对吧?如果3个2就已经是6了,6超过5了喔~

    第3~5个括号:好了,你已经学会了类推法!

     

    怎么乘?

    以初中老师教的方法是第2个括号乘以第1个括号,然后第3个括号乘以上一次相乘的结果....

    一共4步,也就是n-1步,那么i=2to n是不是有n-1步?比如i=2、3、4、5,就是4步嘛。

    接着,两个括号的相乘要怎么办?

    在i的循环内再加一个循环,得把每一步的右边括号里的每个数都要乘以左边括号一次。那j的上下限是多少?下限为0,上限是5,即n。但是过程不是只是自增一,而是自增i个单位,为什么?第1步j的值就会为0、2、4,间隔为2,而第2步中j的值就会为0、3,间隔为3,如果n>5的话,第2步的j的值就会为0、3、6了。所以呢!j=0 to n递增方式(j+=i)。

    此时就完毕了?没呢!

    上一步骤只是将每一步中的右边括号拆出来逐个乘以左边括号,但是左边括号还没拆呢。对于每个j,也就是右边括号里的每个值,都得逐个乘以左边括号里的每个值。那么得再叠加一层循环了,下限为0,上限为5,即为n。又为什么?第1个括号中不是有6位吗,而每个括号中还有个1在最前面,别落下了。这里讲不出思路了,意会吧!

     

    讲代码:

    代码中ans数组先保存第1个括号中的每个系数,也就是全为1,比如ans[0]=1,ans[1]=1.....

    这个数组在同一个i值的情况下不能变化,我本来想用一个数组解决,但是后来发现搞不定,所以开了个辅助数组sup。

    当每次右括号中的一个数乘以左括号时,将相乘的结果累加在sup数组中,整个右括号里的数都乘过一次后,再将sup数组中的值存到ans数组中, 作为临时答案。

    这样子ans中最后保存的就是所要的系数了,ans的下标代表x的几次方,比如ans[4]代表x的4次方的系数。

     

     将整个乘法的过程自己实现一下才知道其精髓,和很多需要注意的地方,看代码实在不是好习惯。

     

     

    本题可用递推、DP等方法来做,但是此题是母函数的入门经典喔~所以我用了母函数

     1 #include <iostream>
     2 #define N 120
     3 using namespace std;
     4 int ans[N+1],sup[N+1];//ans保存答案,sup保存临时值
     5 void main()
     6 {
     7     int num=0,i,j,k;
     8     for(i=0;i<N+1;i++)    //全部初始化为1
     9         ans[i]=1;
    10     for(i=2;i<=N;i++)    // 第i个括号
    11     {
    12         for(j=0;j<=N;j+=i)  //第i个括号中的第j项
    13             for(k=0;k+j<=N;k++)  //临时答案中的第k个数字
    14                 sup[j+k]+=ans[k];   
    15         for(k=0;k<=N;k++)  //每解决一个括号,得将答案保存,后一括号乘以此答案得出新答案
    16             ans[k]=sup[k];
    17         memset(sup,0,sizeof(sup));//临时数组清零
    18     }
    19     while(cin>>k)    //用c++的话得这么写才对
    20         cout<<ans[k]<<endl;
    21 }
    1028

     

  • 相关阅读:
    [Python] from scipy import sparse 报 DLL load failed:找不到指定模块错误
    LPC43xx系列使用IAP的注意事项
    SecureCRT中设置 为回车换行,和 的行为一致
    GSM07.10协议中串口复用的注意事项
    Lua在单片机中的移植
    ALINX公众号
    黑金博客搬家了
    2014年黑金FPGA原创教程规划发布
    【黑金原创教程】【FPGA那些事儿-驱动篇I 】连载导读
    【黑金原创教程】【FPGA那些事儿-驱动篇I 】【实验一】流水灯模块
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4248253.html
Copyright © 2020-2023  润新知