题目
思路
- 凑出价值为
m
m
m的零钱等价于从
v
[
i
]
=
w
[
i
]
v[i]=w[i]
v[i]=w[i] 的01背包中凑出花费了体积为
m
m
m,最大价值为
m
m
m 的方案。
- 我们将零钱金额从大到小排序,那么如果存在相同的方案,后来的字典序一定比之前的字典序小,所以直接更新即可。
AC代码
#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x; i<=y; ++i)
#define per(i,x,y) for(int i=x; i>=y; --i)
#define pushk push_back
#define popk pop_back
#define mem(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define ll long long
#define lp p<<1
#define rp p<<1|1
#define emk emplace_back
using namespace std;
const int N = 1e4+9;
const int M = 1e2+9;
int f[N][M];
bool st[N][M];
int v[N],w[M];
vector<int> ve[108];
int main() {
int n,m;
cin>>n>>m;
rep(i,1,n) cin>>v[i];
sort(v+1,v+n+1,greater<int>());
rep(i,1,n){
rep(j,v[i],m){
f[i][j]=f[i-1][j];
if(f[i-1][j-v[i]]+v[i]>=f[i][j]){
f[i][j]=f[i-1][j-v[i]]+v[i];
st[i][j]=1;
}
}
}
if(f[n][m]==m){
int i=n,j=m;
vector<int> ans;
while(i>=1 && j>=0){
if(st[i][j]){
ans.pushk(v[i]);
j-=v[i];
}
i--;
}
rep(i,0,(int)ans.size()-1) {
if(i) cout<<" ";
cout<<ans[i];
}
}
else{
puts("No Solution");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话