mltang

博客园 首页 新随笔 联系 订阅 管理

题目就是给你

n,m

a1,a2......an   c1,c2.......cn

n种物品,第一种物品价值a1有c1个

问你能组合出多少种不超过m的价格

多重背包+二进制优化(脑补一下其实优化了好多时间啊)

其实不用分成完全背包和多重背包两部分也能过,我这个也是学别人的,之后试了一下不分开写的,也过了

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
bool dp[100005];
int val[105];
int num[105];
int main()
{
    int n,m;
    int i,j,k;
    while (scanf("%d%d",&n,&m) && (n+m))
    {
        for(i=1;i<=n;++i)
            scanf("%d",val+i);
        for(i=1;i<=n;++i)
            scanf("%d",num+i);
        
        memset(dp, false, sizeof(dp));
        dp[0]=true;
        for(i=1;i<=n;++i)
        {
            if(val[i]*num[i]>=m)
            {
                for(j=val[i];j<=m;j++)
                {
                    dp[j] = dp[j-val[i]]||dp[j];
                }
            }
            else
            {
                for(j=1;j<=num[i];j<<=1)
                {
                    for(k=m;k>=j*val[i];--k)
                    {
                        dp[k] = dp[k]||dp[k-val[i]*j];
                    }
                    num[i]-=j;
                }
                if(num[i]>0)
                {
                    for(k=m;k>=val[i]*num[i];--k)
                        dp[k]=dp[k]||dp[k-val[i]*num[i]];
                }
            }
        }
        int cnt = 0;
        for(i=1;i<=m;++i)
            if(dp[i])
                cnt++;
        printf("%d\n",cnt);
        
    }
}

 

posted on 2018-04-13 00:12  mltang  阅读(86)  评论(0编辑  收藏  举报