找零钱问题

来源:互联网 发布:u盘在mac显示不出来 编辑:程序博客网 时间:2024/04/29 05:53
 

/**
 * 问题描述:
 * 设有n种不同的硬币,各硬币面值存储与数组T[1:n]中.现在要用
 * 这些面值的硬币来找钱.
 * 对于任意钱数0<=m<=20001设计一个用最少硬币找钱m的方法
 * 分析与解答:
 * 不防设0<T[1]<T[2]...<T[n]
 * 当只用面值T[1:n]的硬币的时候,可以找出钱数j最少的硬币的个数
 * 是c[i][j],则
 *          c[i-1][j]           j<T[i]
 * c[i][j]=
 *          min{c[i][j-T[i]]+1,c[i-1][j]} j>T[i]
 * 初始条件为:c[1][j]=j/T[1] if j%T[1]==0
 *           c[1][j]=10000000 if j%T[1]!=0
 */
package dynamic;

/**
 * @author Administrator
 *
 */
public class MinCoin {
 /**
  * 常量
  */
 private static final int MAX=100000;
 private static final int M=158;
 /**
  * 私有变量
  */
 private int[] T;
 //private int[] Coin;
 private int num;
 private int[][] c;

 /**
  * 构造函数
  */
 public MinCoin(int[] T,int num) {
  // TODO Auto-generated constructor stub
  this.T=T;
  this.num=num;
  c=new int[num+1][M+1];
  for(int i=1;i<=M;i++)
  {
   if(i%T[1]==0)
   {
    c[1][i]=i/T[1];
   }
   else
   {
    c[1][i]=MAX;
   }
   c[0][i]=MAX;
  }
  for(int j=0;j<=num;j++)
  {
   c[j][0]=0;
  }
 }
 /**
  * 动态规划解决问题
  */
     public void min_coin()
     {
      for(int i=2;i<=num;i++)
      {
       for(int j=1;j<=M;j++)
       {
        if(j>=T[i])
        {
         c[i][j]=(c[i-1][j]>c[i][j-T[i]]+1?c[i][j-T[i]]+1:c[i-1][j]);
        }
        else
        {
         c[i][j]=c[i-1][j];
        }
       }
      }
      int result=MAX;
      for(int i=1;i<=num;i++)
      {
       if(c[i][M]<result)
       {
        result=c[i][M];
       }
      }
      System.out.println(result);
     }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
        int[] T={-1,1,2,5,10};
        MinCoin mc=new MinCoin(T,4);
        mc.min_coin();
 }

}

原创粉丝点击