题解 [ABC286D] Money in Hand
大家好,我是 CQ-C2024 蒟蒻 CJH。
题意
题目翻译很清楚,不懂的再回去看看题面。
分析
这是一道典型的多重背包问题。
朴素算法
注意到数据范围并不需要使用二进制分组优化,所以这里可以拆分成 0-1 背包问题求解。
时间复杂度
二进制拆分优化
考虑长远一点,如果
我们可以使用二进制拆分优化,让复杂度降低。
时间复杂度
代码
朴素算法
//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;
}
谢谢大家!如有错误,欢迎批评指正!
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现