ch_POJ1742 Coins

多重背包可行性贪心+dp解法

就是一个面值已经可以被组成时就尽量少用当前面值的币

#include<iostream>
#include<cstdio>

#define ri register int
#define u int

namespace opt {

    inline u in() {
        u x(0),f(1);
        char s(getchar());
        while(s<'0'||s>'9') {
            if(s=='-') f=-1;
            s=getchar();
        }
        while(s>='0'&&s<='9') {
            x=(x<<1)+(x<<3)+s-'0';
            s=getchar();
        }
        return x*f;
    }

}

using opt::in;

#define NN 100005
#define MM 100005

#include<cstring>

namespace mainstay {

    u N,M,ans,a[NN],c[NN],f[NN],mi[NN];

    inline void solve() {
        while(1) {
            N=in(),M=in(),ans=0;
            if(!N&&!M) return;
            std::memset(f,0,sizeof(f)),f[0]=1;
            for(ri i(1); i<=N; ++i) a[i]=in();
            for(ri i(1); i<=N; ++i) c[i]=in();
            for(ri i(1); i<=N; ++i) {
                std::memset(mi,0,sizeof(mi));
                for(ri j(a[i]); j<=M; ++j) {
                    if(!f[j]&&f[j-a[i]]&&mi[j-a[i]]+1<=c[i]) {
                        mi[j]=mi[j-a[i]]+1,f[j]=1;
                    }
                }
            }
            for(ri i(1); i<=M; ++i) if(f[i]) ++ans;
            std::cout<<ans<<std::endl;
        }
    }

}

int main() {

    //freopen("x.txt","r",stdin);
    std::ios::sync_with_stdio(false);
    mainstay::solve();

}

 多重背包通用优化解法:二进制拆分

#pragma GCC optimize("Ofast")
#include<iostream>
#include<cstdio>

#define ri register int
#define u int

#define NN 100005
#define MM 100005

#include<cstring>

namespace mainstay {

    u N,M,ans,cnt,b[10000005],a[NN],c[NN],f[NN];

    inline void solve() {
        while(1) {
            std::cin>>N>>M;
            ans=cnt=0;
            if(!N&&!M) return;
            std::memset(f,0,sizeof(f)),f[0]=1;
            for(ri i(1); i<=N; ++i) std::cin>>a[i];
            for(ri i(1); i<=N; ++i) {
                std::cin>>c[i];
                u _rest(c[i]);
                for(ri j(1);j<=_rest;j<<=1) b[++cnt]=j*a[i],_rest-=j;    
                b[++cnt]=_rest*a[i];
            }
            for(ri i(1); i<=cnt; ++i) {
                for(ri j(M);j>=b[i];--j){
                    f[j]|=f[j-b[i]];
                } 
            }
            for(ri i(1); i<=M; ++i) if(f[i]) ++ans;
            std::cout<<ans<<std::endl;
        }
    }

}

int main() {

    //freopen("x.txt","r",stdin);
    std::ios::sync_with_stdio(false);
    mainstay::solve();

}

 

posted @ 2019-11-07 15:46  pai_hoo  阅读(100)  评论(0编辑  收藏  举报