《 动态规划_ 货币系统 》

题目描述:

问题 C: 货币系统

时间限制: 1 Sec  内存限制: 128 MB
提交: 349  解决: 104
[提交][状态][讨论版][命题人:外部导入]

题目描述

母牛们不但创建了他们自己的政府而且选择了建立了自己的货币系统。
[In their own rebellious way],,他们对货币的数值感到好奇。
传统地,一个货币系统是由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)。

输入

输入包含多组测试数据

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

第 1 行:  二整数, V 和 N
第 2 ..V+1行: 可用的货币 V 个整数 (每行一个 每行没有其它的数)。

输出

单独的一行包含那个可能的构造的方案数。

样例输入

3 10
1 2 5

样例输出

10







思路:遇见第一个这个题目的时候,就想到了前两天 做过的一个题目 ,就是 硬币的面值只有 1,2,3 三种面值,然后给你一个指定金额 n, 问兑换方式有多少种

这个题目和那个题目唯一不同的就是 一个是硬币的面值是给定的一个是让用户输入的。 本人感觉其实本质就是完全背包(咳咳,没理解完全背包呢,等一会再去学习学习完全背包)

1 . dp[ j ] 表示的的是 总面值是 j , 在有 i 种面值的硬币的情况下有多少种兑换方式,
      i,j 表示 前 i 种 硬币中, 兑换金额为 j 总得兑换方式有多少种。
      
      我感觉有两种,我说的两种可不就是实际的两种, 兑换当前面值的+不兑换当前面值的情况
      状态转移方程 : dp[ j ] = dp[ j] + d[ j - moneyValue[ i ] ]

      举个简单的 栗子
      for(int i = 0;i<n;i++){} 这个是第一重循环,表示遍历的是所有的面值钱币 , 在这个循环里 又有一个循环 是遍历 总金额 从每种 钱币 i的金额开始,一直到 n 结束

      
      最终 dp [ n ] 中存放的就是 总得计算结果
   
这个题目有个小坑 就是 java的 int 过不去,用long 就能过去


Java 实现代码

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     
 5     public static void main(String[] args) {
 6         Scanner cin = new Scanner(System.in);
 7         while(cin.hasNext()){
 8             int v = cin.nextInt();
 9             int n = cin.nextInt();
10             long dp [] = new long [10010];
11             int moneyValue[] = new int [v];
12             for(int i =0;i<v;i++){
13                 moneyValue[i] = cin.nextInt();
14             }
15             dp[0] = 1;
16             for(int i = 0;i<v;i++){
17                 for(int j =moneyValue[i];j<=n;j++){
18                     dp[j] = dp[j]+dp[j-moneyValue[i]];
19                 }
20             }
21             
22             System.out.println(dp[n]);
23         }
24     }
25 
26 }

c++ 实现代码

 1 #include <iostream>
 2 using namespace std;
 3 int main()
 4 {
 5     int moneyVale[10010];
 6     long long dp[10010];
 7     int v,n;
 8     while(cin>>v>>n){
 9         fill(moneyVale,moneyVale+v,0);
10         fill(dp,dp+10005,0);
11         for(int i = 0;i<v;i++){
12             cin>>moneyVale[i];
13         }
14 
15         dp[0] = 1;
16         for(int i = 0;i<v;i++){
17             for(int j = moneyVale[i];j<=n;j++){
18                 dp[j] = dp[j]+dp[j-moneyVale[i]];
19             }
20         }
21         cout<<dp[n]<<endl;
22 
23     }
24     return 0;
25 }


原文地址:https://www.cnblogs.com/kangxinxin/p/10767939.html