poj 1742 背包

n 个物品  背包体积m

n 个物品的价值  n 个物品的数目   

参考http://www.cnblogs.com/xinsheng/archive/2013/12/04/3458362.html

分3种情况

1 个数只有1个    显然是0 1  n*c

2  价值*数目>m  完全背包    n*c

3  用队列优化   这边好像不是单调队列  

#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<iterator>
#include<stack>

using namespace std;

#define ll   __int64
#define MAXN  100010
#define inf  2000000007
#define mod 1000000007
int a[MAXN],c[MAXN];
bool dp[MAXN],q[MAXN];


int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n+m==0)
            break;
        memset(dp,0,sizeof(dp));
        memset(q,0,sizeof(q));
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            scanf("%d",&c[i]);
        dp[0]=1;
        for(int i=1;i<=n;i++)
        {
            if(c[i]==1)
            {
                for(int j=m;j>=a[i];j--)
                    if(dp[j-a[i]])
                        dp[j]=1;
            }
            else if(a[i]*c[i]>=m)
            {
                for(int j=a[i];j<=m;j++)
                    if(dp[j-a[i]])
                        dp[j]=1;
            }
            else
            {
                for(int j=0;j<a[i];j++)//列举每个余下来的
                {
                    int sum=0,st=0,en=-1;
                    for(int v=j;v<=m;v+=a[i])//这边显然是从这个余下来的数 然后去放物品
                    {
                        if(en-st==c[i])//物品数超过了
                            sum-=q[st++];
                        q[++en]=dp[v];//进去
                        sum+=dp[v];    //里面个数
                        if(sum)       //显然要里面有满足条件的  恰好这个或者前面有满足的
                            dp[v]=1;
                    }
                }

            }
        }
        int cnt=0;
        for(int i=1;i<=m;i++)
            if(dp[i])
                cnt++;
        printf("%d\n",cnt);
    }
    return 0;
}

 

     

posted on 2017-04-07 19:16  HelloWorld!--By-MJY  阅读(118)  评论(0编辑  收藏  举报

导航