L3-001. 凑零钱-PAT团体程序设计天梯赛GPLT(01背包,动态规划)
韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩梅梅手边有 104 枚来自各个星球的硬币,需要请你帮她盘算一下,是否可能精确凑出要付的款额。
输入格式:
输入第一行给出两个正整数:N(≤
输出格式:
在一行中输出硬币的面值 V1≤V2≤⋯≤V**k,满足条件 V1+V2+...+V**k=M。数字间以 1 个空格分隔,行首尾不得有多余空格。若解不唯一,则输出最小序列。若无解,则输出 No Solution
。
注:我们说序列{ A[1],A[2],⋯ }比{ B[1],B[2],⋯ }“小”,是指存在 k≥1 使得 A[i]=B[i] 对所有 i<k 成立,并且 A[k]<B[k]。
输入样例 1:
8 9
5 9 8 7 2 3 4 1
输出样例 1:
1 3 5
输入样例 2:
4 8
7 2 4 3
输出样例 2:
No Solution
分析:01背包问题,因为要输出从小到大的排列,可以先把硬币面额从大到小排列,然后用bool类型的
// Murabito-B 21/04/23
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e4 + 10;
int dp[N], w[N];
bool vis[N][N];
void solve() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> w[i];
sort(w + 1, w + 1 + n, greater<int>());
for (int i = 1; i <= n; ++i)
for (int j = m; j >= w[i]; --j)
if (dp[j] <= dp[j - w[i]] + w[i])
vis[i][j] = true, dp[j] = dp[j - w[i]] + w[i];
if (dp[m] != m) cout << "No Solution";
else {
vector<int> a;
int v = m, idx = n;
while (v > 0) {
if (vis[idx][v]) a.push_back(w[idx]), v -= w[idx];
idx--;
}
for (int i = 0; i < a.size(); ++i) cout << a[i] << (i == a.size() - 1 ? "" : " ");
}
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
solve();
return 0;
}
分类:
刷题笔记: PTA
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 5. Nginx 负载均衡配置案例(附有详细截图说明++)