HDU 1028 相似的题目。

方法一:完全背包。

限制条件:硬币总值不超过 n。

目标:求出组合种数。

令 dp[ i ][ j ] == x 表示用前 i 种硬币组合价值为 j 的钱共 x 种方法。

状态转移方程:dp[ i ][ j ] = dp[ i - 1][ j ] + dp[ i ][ j - v[ i ] ] ;

方程解释:用前 i 种硬币组合出钱 j 的方法数 = 前 i - 1 种硬币组合出钱 j 的方法数(不用第 i 种硬币)+ 至少用一枚第 i 种硬币的方法数。

滚动数组实现,i 的这一维便可省去。

代码如下:

 #include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int n,dp[maxn];
void init()
{
memset(dp,,sizeof(dp));
dp[] = ;
for(int i = ; i <= ; ++i)
for(int j = i; j < maxn; ++j)
dp[j] += dp[j-i];
}
int main()
{
init();
while(~scanf("%d",&n))
printf("%d\n",dp[n]);
return ;
}

方法二:母函数。

用( 1 + x^k + x^(k*2) + x^(k*3) + ...) 表示参与组成的价值为 k 的硬币,1 表示硬币 k 个数为 0,每项前面的系数表示组成钱 k ( x 的次方数) 的方法数。

比如现有 1 分,3 分,6 分的硬币各 1 枚,便可得到:

( 1 + x^1 ) * ( 1 + x^3 ) * ( 1 + x^6 ) = 1 + x^1 + x^3 + x^4 + x^6 + x^7 + x^9 + x^10;

这表示用 1 分,3 分,6 分的硬币各 1 枚可以组合出钱数为 0,1,3,4,6,7,9,10 的方法各 1 种。

若是 1 分,3 分,6 分的硬币各 2 枚的话,就可得到:

( 1 + x^1 + x^2 ) * ( 1 + x^3 + x^6 ) * ( 1 + x^6 + x^12 ) =

1 + x^1 + x^2 + x^3 + x^4 + x^5 + 2*x^6 + 2*x^7 + 2*x^8 + x^9 + x^10 + x^11 + 2*x^12 + 2*x^13 + 2*x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + x^20

这表示用 1 分,3 分,6 分的硬币各 2 枚可以组合出

钱数为 0 的方法 1 种,钱数为 1 的方法 1 种,钱数为 2 的方法 1 种,钱数为 3 的方法 1 种,钱数为 4 的方法 1 种,

钱数为 5 的方法 1 种,钱数为 6 的方法 2 种,钱数为 7 的方法 2 种,钱数为 8 的方法 2 种,钱数为 9 的方法 1 种,

钱数为 10 的方法 1 种,钱数为 11 的方法 1 种,钱数为 12 的方法 2 种,钱数为 13 的方法 2 种,钱数为 14 的方法 2 种,

钱数为 15 的方法 1 种,钱数为 16 的方法 1 种,钱数为 17 的方法 1 种,钱数为 18 的方法 1 种,钱数为 19 的方法 1 种,

钱数为 20 的方法 1 种。

(神奇.......要了解更多关于母函数的问题请点这里

手工模拟多项式展开,代码如下:

 #include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int n,ans[maxn],tans[maxn];
void init()
{
for(int i = ; i < maxn; ++i)
{
ans[i] = ;
tans[i] = ;
}
for(int i = ; i <= ; ++i)
{
for(int j = ; j < maxn; ++j)
for(int k = ; j+k < maxn; k+=i)
tans[j+k]+=ans[j];
for(int j = ; j < maxn; ++j)
{
ans[j] = tans[j];
tans[j] = ;
}
}
}
int main()
{
init();
while(~scanf("%d",&n))
printf("%d\n",ans[n]);
return ;
}

向这些博客的作者致谢:

https://www.cnblogs.com/13224ACMer/p/4671551.html

https://blog.csdn.net/u013480600/article/details/40477769

https://blog.csdn.net/feizaoSYUACM/article/details/70040086

https://blog.csdn.net/u010304217/article/details/38374417

HDU 1284(钱币兑换 背包/母函数)的更多相关文章

  1. HDU 1284 钱币兑换问题 母函数、DP

    题目链接:HDU 1284 钱币兑换问题 钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...

  2. HDU 1284 钱币兑换问题(全然背包:入门题)

    HDU 1284 钱币兑换问题(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid=1284 题意: 在一个国家仅有1分,2分.3分硬币,将钱N ( ...

  3. HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包)

    HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包) 题意分析 裸的完全背包问题 代码总览 #include <iostream> #include <cstdio> ...

  4. HDU 1284 钱币兑换问题(普通型 数量无限的母函数)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1284 钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    ...

  5. hdu 1284 钱币兑换问题 完全背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1284 递推公式:dp[i] = sum(dp[i], dp[i-C]) /* 钱币兑换问题 Time ...

  6. hdu 1284 钱币兑换问题 (递推 || DP || 母函数)

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  7. HDU 1284 钱币兑换问题 (完全背包)

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  8. HDU 1284 钱币兑换问题 (动态规划 背包方案数)

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  9. 【完全背包】HDU 1284 钱币兑换问题

    Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于32768. Out ...

随机推荐

  1. 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序

    题目大意 ​ Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...

  2. Codeforces Round #402 (Div. 2) D. String Game

    D. String Game time limit per test 2 seconds memory limit per test 512 megabytes input standard inpu ...

  3. luogu3242 接水果 (整体二分+树状数组)

    考虑整体二分,问题就变成了每个(水果)路径有多少个满足条件(权值)的(盘子)子路径 考虑一个盘子(a,b)表示两端点(不妨设dfn[a]<dfn[b]),那么他能接到的水果(u,v)一定满足(不 ...

  4. 状压DP总结

    状态压缩就是将一行的状态压成一个二进制数,这个数的二进制形式反映了这一行的情况 比如0100111的意义为:这一排的第一个数没被使用,第二个被占用了,第三四个没被占用,第五六七个被占用 我们知道位运算 ...

  5. 20165223 Linux安装及命令入门

    预备作业3:Linux安装及命令入门 一.VirtualBox和Ubuntu的安装 通过学习实践基于VirtualBox虚拟机安装Ubuntu图文教程,我开始学习虚拟机的安装,根据教程一步步试着安装. ...

  6. hihocoder--1384 -- Genius ACM (倍增 归并)

    题目链接 1384 -- Genius ACM 给定一个整数 m,对于任意一个整数集合 S,定义“校验值”如下:从集合 S 中取出 m 对数(即 2*M 个数,不能重复使用集合中的数,如果 S 中的整 ...

  7. yzh的神仙题

    U66905 zz题 考虑一个点权值被计算了多少次...不知 所以对未来承诺,方便直接算上总数! 然后其实是给边定向,即先删除fa和son的哪一个 f[x][j],会计算j次 无法转移 f[x][j] ...

  8. A1118. Birds in Forest

    Some scientists took pictures of thousands of birds in a forest. Assume that all the birds appear in ...

  9. 用宏定义代替printf函数

    来自:http://blog.csdn.net/yannanxiu/article/details/52506451 #define _DEBUG_ 1 #if _DEBUG_ #define PR( ...

  10. file 文件的操作

    1.写入文件: (1)第一种方式    f = open("filename",'mode')  #先打开一个文件,没有的话创建这个文件,mode是模式.有r 只读,w写,rw读写 ...