题目大意:有1、5、10、20、100五种面值的人民币,要用这五种面值凑成n(n大于等于1小于10000),且每种面值的数量不限,求一共有多少种组合方式
题目分析:
使用第1~i种面值的人民币凑成总数k有多少种组合方式呢?有以下几种情况:
1、使用0张i+(1~i-1)组合成k
2、使用1张i+(1~i-1)组合成k-p[i];
3、使用2张i+(1~i-1)组合成k-2*p[i];
…….
m、使用m张i+(1~i-1)组合成k-m*p[i];
…….
直到t,p[i]*t>k,p[i]为第i中人民币的面值
令dp[i][j]表示用前面的1~i种面值凑成j的组合方式总数
经过以上分析可知:若知道了dp[i-1][k]、dp[i-1][k-m*p[i]](m=1,2,3…),就能求出dp[i][k]。很显然这是一个动态规划的问题
public static void solve(int n)
{
//dp[i][j]:表示只使用p[1]~p[i]中的值凑成成j,能有多少种情况
int[] p={0,1,5,10,20,100};
int[][] dp=new int[p.length][n+1];
for(int i=0;i<=n;i++)
{
dp[1][i]=1;
}
for(int i=1;i<p.length;i++)
{
dp[i][0]=1;
}
for(int i=2;i<p.length;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=0;k<=n;k++)
{
if(j-p[i]*k>=0)
dp[i][j]+=dp[i-1][j-p[i]*k];
else
break;
}
}
}
System.out.println(dp[p.length-1][n]);
}