换钱的方法数

//换钱的方法数
public class getCoinSkill{
	
      //获得换钱的数目(暴力递归方法 O(aim^N))
    public static int getCoinNum01(int[]arr,int aim)
    {
    	if(arr==null||arr.length==0||aim<=0)
    	{
    		return 0;
    	}

        return process01(arr,0,aim);
    }

    //书写递归函数
    public static int process01(int[]arr,int index,int aim)
    {

      int res=0;
      if(index==arr.length)
      {
      	res=aim==0?1:0;
      }else
      {
      	for(int i=0;arr[index]*i<=aim;i++)
      	{
      		res+=process01(arr,index+1,aim-arr[index]*i);
      	}
      }

      return res;
    }
//*************************************************************
    //获得换钱的数目(记忆搜索方法O(N*aim^2))
    public static int getCoinNum02(int[]arr,int aim)
    {
    	if(arr==null||arr.length==0||aim<=0)
    	{
    		return 0;
    	}
    	int [][]map=new int[arr.length+1][aim+1];//充当记忆功能
    	return process02(arr,0,aim,map);

    }

    public static int process02(int []arr,int index,int aim,int[][]map)
    { 
    	int res=0;
    	if(index==arr.length)
    	{
    		res=aim==0?1:0;
    	}
    	else{
    		int mapValue=0;
    		for(int i=0;arr[index]*i<=aim;i++)
    		{
    			mapValue=map[index+1][aim-arr[index]*i];//记录已经计算过的值
    			if(mapValue!=0)
    			{
                   
                   res+=mapValue==-1?0:mapValue;
    			}else{

    				res+=process02(arr,index+1,aim-arr[index]*i,map);
    			}

    		}	

    	}
    	map[index][aim]=res==0?-1:res;
        return res;

    }
//*************************************************************
     //获得换钱的数目(动态规划法O(N*aim^2))
	public static int getCoinNum03(int[]arr,int aim)
	{
		if(arr==null||arr.length==0||aim<=0)
		{
			return 0;
		}
		int len=arr.length;
		//生成动态规划表 dp[i][j]的含义是使用arr[0..i]组成钱数j的情况数
		int [][]dp=new int[len][aim+1]; 
		//二维矩阵的第一列
		for(int i=0;i<len;i++)
		{
			dp[i][0]=1;

		}
		//二维矩阵的第一行
		for(int j=1;arr[0]*j<=aim;j++)
		{
            dp[0][arr[0]*j]=1;
		}
		//二维矩阵其他位置dp[i][j]的计算
		int num=0;
		for(int i=1;i<len;i++)
		{
			 for(int j=1;j<=aim;j++)
			 {
			 	num=0;
			 	for(int k=0;j-arr[i]*k>=0;k++)
			 	{
			 		num+=dp[i-1][j-arr[i]*k];//所有情况的累加和
			 	}
			 	dp[i][j]=num;

			 }
		}
		return dp[arr.length-1][aim];
	}
//进阶版动态规划(O(N*aim))
	public static int getCoinNum04(int[]arr,int aim)
	{
		if(arr==null||arr.length==0||aim<0)
		{
			return 0;
		}
		int[][]dp=new int[arr.length][aim+1];
		for(int i=0;i<arr.length;i++)
		{
			dp[i][0]=1;
		}
		for(int j=1;arr[0]*j<=aim;j++)
		{
			dp[0][arr[0]*j]=1;
		}
		for(int i=1;i<arr.length;i++)
		{
			for(int j=1;j<=aim;j++)
			{
				 dp[i][j]=dp[i-1][j];
				 dp[i][j]+=j-arr[i]>=0?dp[i][j-arr[i]]:0;
			}
		}
		return dp[arr.length-1][aim];
	}
//进阶版动态规划加上空间压缩法
	public static int getCoinNum05(int[]arr,int aim)
	{

		if(arr==null||arr.length==0||aim<0)
		{
			return 0;
		}
		int[]dp=new int[aim+1];
		for(int j=0;arr[0]*j<=aim;j++)
		{
			dp[arr[0]*j]=1;
		}
		for(int i=1;i<arr.length;i++)
		{
			for(int j=1;j<=aim;j++)
			{
				dp[j]+=j-arr[i]>=0?dp[j-arr[i]]:0;
			}
		}
		return dp[aim];
	}

	 public static void main(String[]args)
	 {
	 	//System.out.println("Hello");
	 	int []arr={1,2,5,10};//
	 	int aim=10;
	    //暴力递归方法 
	 	System.out.println(getCoinNum01(arr,aim));
	 	//记忆搜索方法
	 	System.out.println(getCoinNum02(arr,aim));
	 	//动态规划法
	 	System.out.println(getCoinNum03(arr,aim));
	 	//进阶版动态规划法
	 	System.out.println(getCoinNum04(arr,aim));
	 	//压缩空间版的动态规划法
	 	System.out.println(getCoinNum05(arr,aim));
	 }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值