hdu 2079(01背包+多重背包或者用母函数)

题意:易理解...

分析:01背包+多重背包,主要思考的是如何避免重复,因为是01背包所以我把同种类型的物品一次装入一个背包里,自己好好思考吧!!这道题挺好的!!!当然用母函数也容易理解,母函数更好理解吧!!

代码实现:

背包实现:
#include<stdio.h>//可以说是01背包+多重背包 #include<string.h> int main() { int T,n,m,i,j,k; int a[10],num[10],dp[45]; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=1;i<=m;i++) scanf("%d%d",&a[i],&num[i]); for(i=1;i<=n;i++) dp[i]=0; dp[0]=1; for(i=1;i<=m;i++) for(j=n;j>=a[i];j--) for(k=1;k<=num[i]&&(j-a[i]*k)>=0;k++)//这个for循环用于避免重复,设置很巧妙,想了很久啊 dp[j]=dp[j]+dp[j-a[i]*k];//就是把一个物品的每种情况都装进容量固定的包里,这里就会避免重复 printf("%d\n",dp[n]); } return 0; }
母函数实现:
#include<stdio.h>
#include<string.h>
int c1[10001],c2[10001];//c1用来记录各项的系数,也就是方案数,c2是用来临时存储的
int main()
{
    int i,j,k,T,n,m,a[10],num[10],t;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;i++)
            scanf("%d%d",&a[i],&num[i]);
        memset(c1,0,sizeof(c1));
        for(i=0,t=0;i<=n&&t<=num[1];i=i+a[1],t++)
            c1[i]=1;
        for(i=0;i<=n;i++)
            c2[i]=0;
        for(i=2;i<=m;i++)
        {
           for(j=0;j<=n;j++)
               for(k=0,t=0;k+j<=n&&t<=num[i];k=k+a[i],t++)
                   c2[j+k]=c1[j]+c2[j+k];   
           for(j=0;j<=n;j++)
           {
               c1[j]=c2[j];
               c2[j]=0;
           }
        }
        printf("%d\n",c1[n]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jiangjing/p/3010802.html