zoukankan      html  css  js  c++  java
  • luogu P3423 [POI2005]BAN-Bank Notes

    Byteotian Bit Bank (BBB) 拥有一套先进的货币系统,这个系统一共有n种面值的硬币,面值分别为b1, b2,…, bn. 但是每种硬币有数量限制ci,现在我们想要凑出面值k求最少要用多少个硬币.

    n<=200,bi<=20000,ci<=20000

    还要输出方案。。。。

    这道题第一眼多重背包,然后打了 ,65分,开O2 70分。。

    我们可以换个思路,何必枚举每种货币选多少个,每次只拿一个,只要记录一下前面状态拿了多少个,判断还有没有剩余就好了。

    当然,第一维for循环不再是枚举货币,而是面值。

    你要用单调队列,二进制拆分也没人拦你QAQ

    Code

      

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define R register
    using namespace std;
    int n,k,b[210],c[210],cnt[210][20010],f[20010],ans[210];
    inline int read(){
        char c=getchar();int x=0,flag=1;
        while(c<'0' || c>'9'){if(c=='-') flag=-1;c=getchar();}
        while(c>='0' && c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();
        return x*flag;
    }
    int main(){
        n=read();
        for(R int i=1;i<=n;i++) b[i]=read();
        for(R int i=1;i<=n;i++) c[i]=read();
        k=read();
        memset(f,0x3f,sizeof(f));f[0]=0;
        for(R int i=1;i<=k;i++){
            int val=0; 
            for(R int j=1;j<=n;j++){
                if(i>=b[j]){
                    if(f[i]>f[i-b[j]]+1 && cnt[j][i-b[j]]<c[j]){
                        f[i]=f[i-b[j]]+1;val=j;
                    }
                }
            }
            cnt[val][i]=cnt[val][i-b[val]]+1;
            for(R int j=1;j<=n;j++) if(j!=val) cnt[j][i]=cnt[j][i-b[val]];
        }
        printf("%d
    ",f[k]);
        for(R int i=1;i<=n;i++) printf("%d ",cnt[i][k]);return 0;
    }
  • 相关阅读:
    Linux 下curl模拟Http 的get or post请求
    ShopNC学习笔记(转)
    (转) shopnc数据库操作
    Mysql开发规范
    长连接、短连接、长轮询和WebSocket
    一个支付宝没有安装app时看不到web网页,无法支付的问题
    MVVM设计模式
    c中的scanf和printf
    import和class关键字的区别
    oc中的注释
  • 原文地址:https://www.cnblogs.com/SyhAKIOI/p/11670768.html
Copyright © 2011-2022 走看看