zoukankan      html  css  js  c++  java
  • [Luogu1474] 货币系统

    Description

    母牛们不但创建了它们自己的政府而且选择了建立了自己的货币系统。由于它们特殊的思考方式,它们对货币的数值感到好奇。

    传统地,一个货币系统是由1,5,10,20 或 25,50, 和 100的单位面值组成的。

    母牛想知道有多少种不同的方法来用货币系统中的货币来构造一个确定的数值。

    举例来说, 使用一个货币系统 {1,2,5,10,...}产生 18单位面值的一些可能的方法是:18x1, 9x2, 8x2+2x1, 3x5+2+1,等等其它。 写一个程序来计算有多少种方法用给定的货币系统来构造一定数量的面值。保证总数将会适合long long (C/C++) 和 Int64 (Free Pascal),即在0 到2^63-1之间。

    Input

    货币系统中货币的种类数目是 V (1<=V<=25)。要构造的数量钱是 N (1<= N<=10,000)。

    第一行: 二个整数,V 和 N 。

    第二行: 可用的货币的面值 。

    Output

    单独的一行包含那个可能的用这v种硬币凑足n单位货币的方案数。

    Sample Input

    3 10
    1 2 5
    
    

    Sample Output

    10
    
    

    题解

    此题实际上也是一个最大化问题,即求组成面值为N的货币最多有多少种方案。可以用DP来做,自底向上的方式求解,以样例为依据推出前I种货币组成面值为J的方案数,如下表所示:

    前I种货币组成面值为J的方案数 0 1 2 3 4 5 6 7 8 9 10
    1 1 1 1 1 1 1 1 1 1 1 1
    2 1 1 2 2 3 3 4 4 5 5 6
    3 1 1 2 2 3 4 5 6 7 8 10

    可见:状态转移方程为(dp[j]+=dp[j-p])

    代码

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    const int N=12000;
    long long dp[N];
    
    int main()
    {
    	int v,n,p,i,j;
    	scanf("%d%d%d",&v,&n,&p);
    	dp[0]=1;
    	for (i=p;i<=n;i+=p) dp[i]=1;
    	for (i=2;i<=v;++i)
    	{
    		scanf("%d",&p);
    		for (j=p;j<=n;++j) dp[j]+=dp[j-p];
    	}
    	cout<<dp[n]<<endl;
    	return 0;
    }
    

    本文作者:OItby @ https://www.cnblogs.com/hihocoder/

    未经允许,请勿转载。

  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/hihocoder/p/10387708.html
Copyright © 2011-2022 走看看