整数的拆分3

来源:互联网 发布:算法爱好者 编辑:程序博客网 时间:2024/05/18 01:52

递推关系的确定

   设n的“最大零数不超过m” 的分划式个数为q(n, m),这里m<=n,则

                  q(n,n)=1+q(n, n-1)

   等式右边的“1”表示n等于n本身;q(n,n-1)表示n的所有其他分划,即最大零数不超过n-1的分划。

                  q(n,m)=q(n,m-1)+q(n-m,m)  (1<m<n)

    其中q(n,m-1)表示零数中不包含m的分划式数目;q(n-m,m)表示零数中包含m的分划数目,因为如果确定了一个分划的零数中包含m,则剩下的部分就是对于n-m进行不超过m的分划。

    注意:如果n-m<m时,取q(n-m,m)=q(n-m,n-m),初始条件:q(n,0)=0, q(1,m)=1

使用递推方法

// 整数分划递推计数  #include <stdio.h>  #include <math.h>    int main()  {      int s, m, n;      long q[121][121];        printf("请输入整数:");  // 输入分划的整数      scanf("%d", &s);        for (m = 1; m <= s; m++) {   // 确定初始条件          q[m][0] = 0;          q[1][m] = 1;      }      for (n = 2; n <= s; n++) {          for (m = 1; m <= n -1; m++) {              if (n - m < m)                  q[n - m][m] = q[n -m][n - m];              q[n][m] = q[n][m - 1] + q[n - m][m];    // 实施递推          }          q[n][n] = q[n][n - 1] + 1;                  // 加上n=n这一个分划式      }        printf("整数%d的分划种数:%ld\n", s, q[s][s]);        return 0;  }  
改进:现在要求整数只能拆分成1,2,4,10,20,40,100,200,400,1000,2000这11个数

使用递推方法:

b[i]为第i种货币含5分硬币的数量(1<=i<=11)

m[i][j]用前i种货币构成j个5分硬币的方案数,前i种货币构成j个5分硬币的方式数是在前i-1种货币基础上构成


代码如下:

public class Demo2 {int b[] = {1,2,4,10,20,40,100,200,400,1000,2000} ;int target  ;public Demo2(int target){this.target = target ;}public int compute(){int m[][] = new int[b.length+1][target+1] ;for(int j=0;j<target+1;j++){m[0][j] = 0 ;}for(int i=0;i<b.length+1;i++){m[i][0] = 1 ;}for(int i=1;i<b.length+1;i++){for(int j=1;j<target+1;j++){m[i][j] = 0 ;int temp = j ;do{m[i][j] = m[i][j] + m[i-1][temp] ;temp = temp - b[i-1] ;}while(temp>=0) ;}}return m[b.length][target] ;}public static void main(String args[]){Demo2 demo = new Demo2(200) ;int result = demo.compute() ;System.out.println(result);}}



0 0