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 (母函数 | 多重背包)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode Coin Change

Leetcode322. coin-change

LeetCode 518. Coin Change 2

[LeetCode] Coin Change

322. Coin Change

leetcode笔记:Coin Change