题解 [ABC286D] Money in Hand

大家好,我是 CQ-C2024 蒟蒻 CJH。

题意

题目翻译很清楚,不懂的再回去看看题面。

分析

这是一道典型的多重背包问题。

朴素算法

注意到数据范围并不需要使用二进制分组优化,所以这里可以拆分成 0-1 背包问题求解。

时间复杂度 O(Xi=1NBi)

二进制拆分优化

考虑长远一点,如果 Bi 的数据范围再大一点,肯定无法使用朴素算法。

我们可以使用二进制拆分优化,让复杂度降低。

时间复杂度 O(Xi=1Nlog2Bi)

代码

朴素算法

//the code is from chenjh
#include<cstdio>
int n,x,a[55],b[55];
bool c[10001];
int main(){
    scanf("%d%d",&n,&x);
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
    c[0]=1;
    for(int i=1;i<=n;i++)for(int j=1;j<=b[i];j++)for(int k=x;k>=a[i];k--)//单个拆分求解。
        c[k]|=c[k-a[i]];
    puts(c[x]?"Yes":"No");
    return 0;
}

二进制拆分优化

//the code is from chenjh
#include<cstdio>
int n,x,a[55],b[55];
bool c[10001];
int min(int x,int y){return x<y?x:y;}
int main(){
    scanf("%d%d",&n,&x);
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
    c[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;b[i]>0;j<<=1){//二进制分组优化求解。
            j=min(j,b[i]),b[i]-=j;
            for(int k=x;k>=j*a[i];k--) c[k]|=c[k-j*a[i]];
        }
    }
    puts(c[x]?"Yes":"No");
    return 0;
}

谢谢大家!如有错误,欢迎批评指正!

posted @   Chen_Jinhui  阅读(6)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现

一言

失礼。噛みました
——化物语(上)
点击右上角即可分享
微信分享提示