多重背包 二进制优化

例题 蓝书p280
https://ac.nowcoder.com/acm/problem/51167

在这里插入图片描述
输入

3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0

输出
8
4

代码

#include <stdio.h>
#include <string.h>
int w[1000],a[1000];
bool f[100010];
int main()
{
    int n,m,c,tem,ans,pos;
    while(scanf("%d %d",&n,&m)&&n&&m)
    {
    	ans=0;
    	pos=0;
    	memset(f,0,sizeof(f));
    	f[0]=1;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&c);
            tem=1;
            while(c)          //将c用二进制分解成 1 2 4 8 .。。。和剩下的余数
            {
                if(c>=tem)
                {
                    c-=tem;
                    w[++pos]=tem*a[i];
                }
                else
                {
                    w[++pos]=c*a[i];
                    c-=c;
                }
                tem*=2;
            }
        }
        for(int i=1;i<=pos;i++)       //当作01背包
            for(int j=m;j>=w[i];j--)
                f[j]|=f[j-w[i]];
        for(int i=1;i<=m;i++)
            ans+=f[i];
        printf("%d\n",ans);
    }
}
发布了88 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44879687/article/details/102992750