hdu 1085



hdu 1085

#include<iostream>

#include<cstring>

using namespace std;

const int maxexp=1*1000+2*1000+5*1000;//由题目每种钱的个数不大于1000得数组最大长度

int main(){

int c1[maxexp],c2[maxexp],c3[maxexp],n1,n2,n3;//c1,c2,c3分别代表母函数的系数,n1,n2,n3代表钱的个数

bool false;//用于最后两种情况的输出,一种是在最大的幂之前找到为0的系数,另一种是为找到即为最大的幂加1

while(scanf("%d%d%d",&n1,&n2,&n3 && n1+n2+n3>0){

memset(c1,0,sizeof(c1));//先将数组置为0

memset(c2,0,sizeof(c1));

memset(c3,0,sizeof(c1));

for(int i=0;i<=n1;i++)//将钱为1的个数系数置为1,1+x+x^2+...+x^n1

c1[i]=1;

for(int j=0;j<=n1;j++)//将钱为2的个数和为1的个数进行合并同类项给c2

for(int m=0;m<=2*n2;m+=2)

c2[j+m]+=c1[j];

for(int h=0;h<=n1+2*n2;h++)//将钱为2的个数和为1的个数还有为5的个数进行合并同类项给c3

for(int m=0;m<=5*n3;m+=5)

c3[h+m]+=c2[h];

f=false;

for(int y=0;y<n1+2*n2+5*n3;y++)

if (c3[y]==0)  

            {  

                printf("%d\n", y);  

                f=true;  

                break;  

            }  

        if (!f) printf("%d\n", n1+2*n2+5*n3+1);//如果在最大幂之前未找到,就输出n1+2*n2+5*n3+1

}

return 0;

}

这是一道关于母函数的题,要想做出这道题首先要理解母函数如何使用。

母函数总结:(求一个值n的划分方法)

  {由形如(1+x^1+x^2+x^3+..+x^n)*(1+x^2+x^4+x^6+...+x^n)*...*(1+x^n)

(指数可能代表:一种值的整数,一种砝码的质量,一种硬币的面值,一种邮票等等。)

求出G(x)=a0*x^0+a1*x^1+a2*x^2+a3*x^3+....+an*x^n;中的an。

解决方法:

由第一个式分别和后面的式子相乘,合并同类项

模板代码实现:

for(int i=2;i*m<=n;i++)///m=0,1,2,3,....

{

For(intj=0;j<=n;j++)

{

For(int k=0;k*(m*i)+j<=n;k++)

{

C2[k*i+j]+=c1[j];

      }

//或则for(intk=0;k+j<=n;k+=i*m)

//{

///C2[k+j]+=c1[j];

//}

   }

  For(k=0;k<=n;k++)

 

    C1[k]=c2[k];

    C2[k]=0;

   }

}

Printf(“%d”,c1[n]);

如若已经求得序列的母函数G(x),则该序列也随之确定。 序列a0,a1,a2,…可记为{an} 
如何用母函数来解决诸如整数拆分、邮票组合、砝码称重一类的问题?这一类问题大致是需要找到整数拆分的方案数,邮票可以组合出多少面额,某一种重量可以由多少种砝码组合来完成称重……当然利用类似动态规划的思想往往也可以解决这类问题,下面讨论怎么使用母函数来完成。


“例1:若有1克、2克、3克、4克的砝码各一 枚,能称出哪几种重量?各有几种可能方案? 
如何解决这个问题呢?考虑构造母函数。如果用x的指数表示称出的重量,则:
  1个1克的砝码可以用函数1+x表示,1个2克的砝码可以用函数1+x2表示,
  1个3克的砝码可以用函数1+x3表示,1个4克的砝码可以用函数1+x4表示,
几种砝码的组合可以称重的情况,可以用以上几个函数的乘积表示:
(1+x)(1+x^2)(1+x^3)(1+x^4)
=(1+x+x^2+x^3)(1+x3+x^4+x^7)
=1+x+x^2+2x^3+2x^4+2x^5+2x^6+2x^7+x^8+x^9+x^10  
从上面的函数知道:可称出从1克到10克,系数便是方案数。
理解了这个例子之后整数拆分、邮票组合、砝码称重一类的问题就都一并解决了。
下面来是我对这种母函数构造方式的理解。
对于上面的例1,如果取消砝码个数的限制,则母函数变为G(x)=(1+x+x^2+,,,,,)(1+x^2+x^4+...)(1+x^3+x^6+...)(1+x^4+x^8+..)
若要称量重量M,那么这个质量M就对应母函数展开后的x^M项。而x^M项的指数M按照数学上的展开来理解是什么来的呢?
假设M=14,我们用1个1g砝码,1个2g砝码,1个3g砝码和2个4g砝码。则可以看做是从G(x)=(1+x+x^2+,,,,,)(1+x^2+x^4+...)(1+x^3+x^6+...)(1+x^4+x^8+..)的每一个括号(每个括号分别对应1g, 2g, 3g, 4g砝码单独可以组合出哪些质量)里取出了x, x^2, x^3, x^8。然后意会一下为什么x^M项对应的系数就是称量质量M的方案数了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值