zoukankan      html  css  js  c++  java
  • 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
    ",cnt);
        }
        return 0;
    }

         

  • 相关阅读:
    P2761 软件补丁问题
    CF1335F Robots on a Grid
    [bzoj2088]P3505 [POI2010]TEL-Teleportation
    CF1335E Three Blocks Palindrome
    P3831 [SHOI2012]回家的路
    P4568 [JLOI2011]飞行路线(分层图)
    P4774 [NOI2018]屠龙勇士
    P2480 [SDOI2010]古代猪文
    CF #632 (Div. 2) 对应题号CF1333
    BSGS 和扩展
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6679659.html
Copyright © 2011-2022 走看看