hdu 1284完全背包

http://acm.hdu.edu.cn/showproblem.php?pid=1284

 

 

 

 

钱币兑换问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7265    Accepted Submission(s): 4268


Problem Description
在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法。请你编程序计算出共有多少种兑法。
 

 

Input
每行只有一个正整数N,N小于32768。
 

 

Output
对应每个输入,输出兑换方法数。
 

 

Sample Input
2934 12553
 

 

Sample Output
718831 13137761
 

 

Author
SmallBeer(CML)
 

 

Source
 

 

Recommend
lcy
 

 

Statistic |  Submit |  Discuss |  Note
Hangzhou Dianzi University Online Judge 3.0
Copyright © 2005-2015 HDU ACM Team. All Rights Reserved.
Designer & Developer Wang Rongtao LinLe GaoJie GanLu
Total 0.002001(s) query 2, Server time : 2015-05-28 22:32:58, Gzip enabled

 

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int dp[35000];
 5 int main()
 6 {
 7     int a[5]= {0,1,2,3};
 8     dp[0]=1;
 9     for(int i=1; i<=3; i++)
10     {
11         for(int j=i; j<35000; j++)
12         {
13             dp[j]+=dp[j-a[i]];//为什么要dp[j-a[i]],因为每次执行这一步,都是假设再用一枚当前硬币,所以要加上减去这枚硬币以后的钱数的方法数
14         }
15     }
16     int n;
17     while(scanf("%d",&n)!=EOF)
18         cout<<dp[n]<<"\n";
19     return 0;
20 }
21 
22 
23 
24 /*
25 方法2:
26 转:
27 思路:首先看能兑换多少个三分硬币的,然后当三分硬币分别为1,2,3,.... n时有多少
28 个2分硬币的,为什么要这样确定了?因为只要还可以兑换出三分硬币和二分硬币的那么
29 剩下的价值一定可以让价值为1的硬币塞满。开头为什么s为N/3+1呢?因为可以这样想,
30 假设N=7,那么只包含3分硬币和1分硬币的组合方式为:3,3,1; 3,1,1,1,1;
31 所以N/3是实际上可以容纳三分硬币的个数。而增加1是因为可以全部换成1分的硬币。
32 有人会疑问,那么t = (N-3*i)/2不是会重复吗?这是不可能的,因为硬币的价值是递
33 增的,只有当i的值为N/3时,t的值可以为0或者1。所以不会重复。
34 */
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 using namespace std;
40 int N;
41 int main()
42 {
43     while(~scanf("%d", &N))
44     {
45         int s = N/3+1;
46         for(int i = 0 ; i <= N/3 ; i++)
47         {
48             int t = (N-3*i)/2;
49             s += t;
50         }
51         printf("%d\n", s);
52     }
53     return 0;
54 }
55 
56 /*方法3:(母函数)
57 题目的意思就是说给你三种面值的币分别是1分、2分、3分,那么问你一个钱数n有几种方案可以拼凑得到这个钱数n?
58 这道题还是比较好看的,我们根据母函数的定义,以及多项式的每一项和系数所表示的含义,我们可以定义母函数G(x)=(1+x+x^2+x^3--------)*(1+x^2+x^4+x^6+x^8--------)*(1+x^3+x^6+x^9--------------),那么我们使用母函数的额展开式对应的指数就是能表示的钱币数,系数就是表示该钱币数的方案数。
59 所以问题就是求出对应的n的系数就可以了,这个比较简单,就是模拟手工多项式的展开,
60 
61  */
62 #include <cstring>
63 #include <cstdlib>
64 #include <cstdio>
65 using namespace std;
66 const int Max=32769;
67 int ans[Max];
68 int tans[Max];
69 int main()
70 {
71     int i,j,n;
72     for(int i=0; i<Max; i++)
73         ans[i]=1;
74     memset(tans,0,sizeof(tans));
75     for(int k=2; k<=3; k++)
76     {
77         for(i=0; i<Max; i++)
78         {
79             for(j=0; i+j<Max; j+=k)
80             {
81                 tans[i+j]+=ans[i];
82             }
83         }
84         for(i=0; i<Max; i++)
85         {
86             ans[i]=tans[i];
87             tans[i]=0;
88         }
89     }
90     while(scanf("%d",&n)!=EOF)
91     {
92         printf("%d\n",ans[n]);
93     }
94     return 0;
95 }

 

转载于:https://www.cnblogs.com/SSYYGAM/p/4537173.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值