HDU-2016 Coin Change (母函数 | 多重背包)
Posted tianwell
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-2016 Coin Change (母函数 | 多重背包)相关的知识,希望对你有一定的参考价值。
题意:给你多组数据,然后给出一个面额n,已知有5种钱币1, 5 ,10 , 25, 50求可以组成n元的可能数 (同时所花费的钱币个数要小于等于100)
思路:从多重背包来理解,即使每个硬币占一个单位空间,有100个空间通过状态转移方程:dp[j][k] += dp[j-v[i]][k-1]; 这里dp记录的便是组合的种类数(相当于递推公式,
从dp[0][0]这个状态开始,尝试放入不同的硬币并且符合条件)
总母函数的角度:同样相当于取5种类型的硬币,然后通过母函数性质模拟多项式乘积 便可以得到
多重背包完整代码:
#include<cstdio> #include <algorithm> #include <cstring> using namespace std; int a[255][105],b[255][105]; int v[6]=0,1,5,10,25,50; int dp[110][300]; int num[255]=0; int i,j,k,t,n; int ans ; void solve() memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=1;i<=5;i++) for(int j=1;j<=100;j++) for(int k=250;k>=v[i];k--) dp[j][k]+=dp[j-1][k-v[i]]; int main() solve();//预处理 while(~scanf("%d",&n)) ans= 0; for(int i =0;i<=100;i++) ans +=dp[i][n]; printf("%d\n",ans); return 0;
母函数完整代码:
#include<cstdio> int a[255][105],b[255][105]; int v[6]=0,1,5,10,25,50; int num[255]=0; int i,j,k,t,n; void solve() a[0][0]=1; for(i=1;i<=5;i++)//种类数 for(j=0;j<=250;j++)//最大额度 for(k=0;j+k*v[i]<=250;k++) for(t=0;t+k<=100;t++)//硬币个数限制 b[j+k*v[i]][t+k]+=a[j][t]; for(j=0;j<=250;j++)//赋值与清零 for(t=0;t<=100;t++) a[j][t]=b[j][t]; b[j][t]=0; for(i=0;i<=250;i++)//将系数相加(即为组合可能数) for(j=0;j<=100;j++) num[i]+=a[i][j]; int main() solve();//预处理 while(~scanf("%d",&n)) printf("%d\n",num[n]); return 0;
以上是关于HDU-2016 Coin Change (母函数 | 多重背包)的主要内容,如果未能解决你的问题,请参考以下文章