美团笔试-人民币

来源:互联网 发布:java 双亲委派 编辑:程序博客网 时间:2024/04/30 14:59

题目大意:有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]);    }
0 0
原创粉丝点击