//换钱的方法数
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));
}
}
换钱的方法数
最新推荐文章于 2019-12-27 09:35:03 发布