组合成n分钱

有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱,求有多少种组合可以组合成n分钱?
方案一:
for()循环嵌套  

public class Coin
{
public static void main(String [] args)
{
int sum=0;
System.out.println("Input a number is n:"); //输入一个n的值
Scanner input = new Scanner(System.in);
int n=input.nextInt();
for(int i=0;i<=n/10;i++) // 10 分 的个数
for(int j=0;j<=(n-10*i)/5;j++) //5分 的个数
for(int m=0;m<=(n-10*i-5*j)/2;m++) // 2 分的个数
for(int t=0;t<=n-10*i-5*j-2*m;t++) // 1分的个数
if(10*i+5*j+2*m+t==n) // 判断是不是 相等
  sum++;
System.out.println(sum);
}
}
方案2:
  1. int count=0;  
  2. int Target=0;  
  3.   
  4. int coin[4]={1,2,5,10};  
  5. int total=0;  
  6. vector<<span class="datatypes" style="margin: 0px; padding: 0px; border: none; color: rgb(46, 139, 87); background-color: inherit; font-weight: bold; ">intsolution;  
  7.   
  8. void dfs(int index)  
  9.  
  10.     iftotal == Target  
  11.      
  12.         count++;  
  13.         cout << count <<":"  
  14.         forint i=0; i<(int)solution.size(); i++)  
  15.          
  16.             cout  << solution[i]<<" 
  17.          
  18.         cout << endl;  
  19.         return 
  20.      
  21.   
  22.     iftotal Target  
  23.         return 
  24.   
  25.     forint i=index; i<4; i++)  
  26.      
  27.         total += coin[i];  
  28.         solution.push_back( coin[i] );  
  29.         dfs(i);  
  30.         solution.pop_back();  
  31.         total -=coin[i];  
  32.      
  33.  
  34.   

  35.     while(1)  
  36.      
  37.         count=0;  
  38.         cin >> Target;  
  39.         dfs(0);  
  40.         cout << count <<endl;  
  41.      
  42. 刚一同事说使用 动态规划和母函数来求解,呵呵,听起来不错!

从递推关系说起

研究以下等式:

 母函数及其应用(Generation function) - linjianxionggo - 为自己而战

   
可以看出: 
x2项的系数a1a2+a1a3+...+an-1an中所有的项包括n个元素a1,a2, …an中取两个组合的全体;同理x3项系数包含了从n个元素a1,a2, …an中取3个元素组合的全体。以此类推。
   
若令a1=a2= …=an=1,在(2-1-1)式中a1a2+a1a3+...+an-1an项系数中每一个组合有1个贡献,其他各项以此类推。故有: 
母函数及其应用(Generation function) - linjianxionggo - 为自己而战
 

 母函数定义:

对于序列a0,a1,a2,…构造一函数:

母函数及其应用(Generation function) - linjianxionggo - 为自己而战   
称函数G(x)是序列a0,a1,a2,…的母函数 
For example:
(1+x)n是序列C(n,0),C(n,1),...,C(n,n)的母函数。 
        如若已知序列a0,a1,a2,…则对应的母函数G(x)便可根据定义给出。 
反之,如若已经求得序列的母函数G(x),则该序列也随之确定。 
        序列a0,a1,a2,…可记为{an} 。   
实 例 分 析
例一、若有1克、2克、3克、4克的砝码各一 枚,能称出哪几种重量?各有几种可能方案? 
如何解决这个问题呢?考虑构造母函数。 
如果用x的指数表示称出的重量,则: 
1个1克的砝码可以用函数1+x表示, 
1个2克的砝码可以用函数1+x2表示, 
1个3克的砝码可以用函数1+x3表示, 
1个4克的砝码可以用函数1+x4表示

几种砝码的组合可以称重的情况,可以用以上几个函数的乘积表示: 
(1+x)(1+x2)(1+x3)(1+x4) 
=(1+x+x2+x3)(1+x3+x4+x7) 
=1+x+x2+2x3+2x4+2x5+2x6+2x7+x8+x9+x10 

从上面的函数知道,可称出从1克到10克,系数便是方案数。
例如右端有2x5 项,即称出5克的方案有2:5=3+2=4+1,同样,6=1+2+3=4+2;10=1+2+3+4。故称出6克的方案有2,称出10克的方案有1 
例二、求用1分、2分、3分的邮票贴出不同数值的方案数。   
因邮票允许重复,故母函数为
母函数及其应用(Generation function) - linjianxionggo - 为自己而战
     
以展开后的x4为例,其系数为4,即4拆分成1、2、3之和的拆分数为4,即 : 
4=1+1+1+1=1+1+2=1+3=2+2
 
概念:整数拆分 
所谓整数拆分即把整数分解成若干整数的和,相当于把n个无区别的球放到n个无标志的盒子,盒子允许空着,也允许放多于一个球。整数拆分成若干整数的和,办法不一,不同拆分法的总数叫做拆分数。 
   
例3:若有1克砝码3枚、2克砝码4枚、4克砝码2枚,问能称出哪几种重量?各有几种方案? 
例4: 整数n拆分成1,2,3,…,m的和,求其母函数。如若其中m至少出现一次,其母函数又如何? 
请自己写出以上两个问题的母函数。
如何编写程序
实现母函数的应用呢?
关键:对多项式展开

以整数拆分为例:
观察以下的母函数:
母函数及其应用(Generation function) - linjianxionggo - 为自己而战
代码如下:
#include<iostream>
using namespace std;
int main()
{
      int a[121],b[121],i,j,k,n;
      while(cin>>n)
      {
              for(i=0;i<=n;i++)
    {
      b[i]=0;
      a[i]=1;//初始化a,由母函数(1+x+x^2+..x^n)初始化,把0-n系数初始化为1
    }
              for(i=2;i<=n;i++)//i表示的是第i个表达式(母函数的相乘的那个表达式),从2遍历到n
              {
                      for(j=0;j<=n;j++)//j表示的是第i个表示中第j个数,如(1+x+x^2+x^3+…) j=2;j表示的是x^2;
                              for(k=0;k+j<=n;k+=i)//k表示的是第j的指数,所以每次k值增i(因为第i个表达式增值为i)
                                      b[j+k]+=a[j];
        for(k=0;k<=n;k++)
          a[k]=b[k],b[k]=0;
              }
              cout<<a[n]<<endl;
      }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值