杭电1284钱币兑换问题—背包dp/母函数(java)

简介: 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法。请你编程序计算出共有多少种兑法。

Problem Description


在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法。请你编程序计算出共有多少种兑法。


Input


每行只有一个正整数N,N小于32768。


Output


对应每个输入,输出兑换方法数。


Sample Input


2934

12553


Sample Output


718831

13137761

母函数暂时不会,只能用背包做,dp[i][j]表示使用前i种钱换成j的总共方式。首先要考虑初始问题,dp[i][0]=1;有再多的钱换成0元只有一种方式。dp[1][a[1]* q]=1; 这个表示第一种钱的倍数有一种方式,比如表示第一种钱是3块的时候,dp[1][3]表示一张三块,dp[1][3*2]表示6块钱刚好可以用两张三块钱表示。


正常情况下的核心状态转移方程为

if(i>j) {dp[i][j]=dp[i-1][j];}无法使用第i种钱,就是使用i-1种钱抓取j的方式数

else {dp[i][j]=dp[i-1][j] dp[i][j-a[i]];}可以使用第i张,总个数就是不适用第i种的加上使用第i种的,不使用第i种就是dp[i-1][j],使用了i种就是dp[i][j-a[i]];其实这里有一个递归/调用自己的过程,使用了一张后dp[i][j-a[i]]在重新判断这个数能否使用i,如果能使用,再次拆分,一直拆到最后无法使用i为止。


附上代码:


import java.util.Scanner;
/*
 * 找零钱问题背包问题
 */
public class 杭电1284 {
  public static void main(String[] args) {  
   Scanner sc=new Scanner(System.in);
   int dp[][]=new int[4][32768];   
   for(int i=1;i<4;i ) {dp[i][0]=1;}
   for(int j=1;j<32768;j ) {dp[1][j]=1;}//这里a[i]刚好为i所以a[1]=1;可以简化不用数组
   for(int i=1;i<4;i ) 
   {
   for(int j=1;j<32768;j )
   {
     if(i>j) {dp[i][j]=dp[i-1][j];}
     else
       dp[i][j]=dp[i-1][j] dp[i][j-i];//a[i]=i;就一分,两分,三分。
   }
   }
   while(sc.hasNext())
   {
     int n=sc.nextInt();
     System.out.println(dp[3][n]);
   }
  }    
  }


希望后面学了母函数能够在用母函数写出来!

更新母函数代码,直接套模板即可


import java.util.Scanner;
public class hdu1284 {
  static long c1[];
  static long c2[];
  public static void main(String[] args)
  {
    Scanner sc=new Scanner(System.in);
    c1=new long[32769];
    c2=new long[32769];
    sovle(32768);
    while(sc.hasNext())
    {
      int t=sc.nextInt();
      System.out.println(c1[t]);
    }
  }
  private static void sovle(int n) {
    // TODO 自动生成的方法存根
    for(int i=0;i<=n;i )
    {
      c1[i]=1;
      c2[i]=0;
    }
    for(int i=2;i<=3;i )
    {
      for(int j=0;j<=n;j )
      {
        for(int k=0;k j<=n;k =i)
        {
          c2[k j] =c1[j];
        }
      }
      for(int j=0;j<=n;j )
      {
        c1[j]=c2[j];c2[j]=0;
      }
    }
  }
}
目录
相关文章
|
5月前
|
Java
杭电 OJ 1010-1019 Java解法(未更新完毕)
杭电 OJ 1010-1019 Java解法(未更新完毕)
27 1
|
5月前
|
Java
杭电acm1201 18岁生日 Java解法 时间类
杭电acm1201 18岁生日 Java解法 时间类
27 0
|
5月前
|
算法 Java
杭电 OJ 1000-1009 Java解法
杭电 OJ 1000-1009 Java解法
24 0
|
5月前
|
Java
杭电acm2018 母牛的故事 Java解法 经典递归
杭电acm2018 母牛的故事 Java解法 经典递归
26 0
|
5月前
|
Java BI
杭电acm1013 Digital Roots 数字根 Java解法 高精度
杭电acm1013 Digital Roots 数字根 Java解法 高精度
28 0
【Java每日一题,dp预处理+回溯】回文串分割
【Java每日一题,dp预处理+回溯】回文串分割
|
Java 索引
【Java】dp数组的遍历方向
文章目录 前言 创建数组 反向遍历 分析 斜向遍历 分析
【Java】dp数组的遍历方向
|
Java
蓝桥杯节点选择(java)第一道树形dp分析
有一棵 n 个节点的树,树上每个节点都有一个正整数权值。如果一个点被选择了,那么在树上和它相邻的点都不能被选择。求选出的点的权值和最大是多少?
216 0
蓝桥杯节点选择(java)第一道树形dp分析
|
算法 Java 索引
【Java】dp--最长递增子序列
文章目录 前言 1.dp数组的定义 2.base case 3.代码
|
Java
杭电6318(归并排序)逆序数(java)
归并排序是采用分冶实现的,其核心思想就是分冶得到两边经过递归是有序的,(因为分到最后就是两个元素的比较。
92 0