zoukankan      html  css  js  c++  java
  • [POI2005]Bank notes

    link

    试题分析

    我们发现此题是一个十分简单的多重背包。但是按照朴素写法会超时。所以要去考虑优化。

    我们发现我们若$W=7$,可以拆成$1+2+4$,不用每次$1+1+1+1+1+1+1$,从$N$级就变成$log$级了。所以对于每一组$(w_i,c_i)$,我们都可以拆成多个二进制数,然后暴力去写即可。

    时间复杂度:$O(k imes sum_{i=1}^n log_2 C_i).$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int N=1e6+1;
    int n,w[N],c[N],f[N],k,W[N];
    void solve(int wi,int ci,int numi){
        int t=1;
        while(numi>=t){
            w[++w[0]]=wi*t;
            c[++c[0]]=t;
            numi-=t;
            t<<=1;
        }
        w[++w[0]]=wi*numi;
        c[++c[0]]=numi;
        return;
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++) W[i]=read();
        for(int i=1;i<=n;i++){
            int num=read();
            solve(W[i],1,num);
        }
        memset(f,127/3,sizeof(f));f[0]=0;
        k=read();n=w[0];
        for(int i=1;i<=n;i++)
            for(int j=k;j>=w[i];j--) f[j]=min(f[j],f[j-w[i]]+c[i]); 
        cout<<f[k];
    }
    View Code
  • 相关阅读:
    [原创]推荐三款强大且漂亮的统计图控件
    使用ATL设计组件(VC6.0)
    COM笔记引用计数
    远程调试
    记事本2
    C++中类的多态与虚函数的使用
    Eclipse常用快捷键
    怎么在Release下调试代码
    MSDN 无法显示网页
    COM笔记接口
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10139146.html
Copyright © 2011-2022 走看看