P2725 [USACO3.1] 邮票 Stamps
P2725 [USACO3.1] 邮票 Stamps
题目描述
给一组 $n$ 枚邮票的面值集合和一个上限 $k$ —— 表示信封上能够贴 $k$ 张邮票。请求出最大的正整数 $m$,满足 $1$ 到 $m$ 的面值都可以用不超过 $k$ 张邮票表示出来。
输入格式
输入的第一行是两个整数,分别代表邮票上限 $k$ 和邮票面值数 $n$。
自第二行起,除最后一行外,每行有 $15$ 个整数 $a_i$ ,最后一行的整数个数不超过 $15$,共有 $n$ 个整数,第 $i$ 个整数代表第 $i$ 种邮票的面值 $a_i$。
输出格式
输出一行一个整数代表 $m$。若 $m$ 不存在请输出 $0$。
输入输出样例 #1
输入 #1
5 2
1 3
输出 #1
13
说明/提示
样例输入输出 1 解释
有 $1$ 分和 $3$ 分的邮票;你最多可以贴 $5$ 张邮票。很容易贴出 $1$ 到 $5$ 分的邮资(用 $1$ 分邮票贴就行了),接下来的邮资也不难:
- $6 = 3 + 3$。
- $7 = 3 + 3 + 1$。
- $8 = 3 + 3 + 1 + 1 $。
- $9 = 3 + 3 + 3 $。
- $10 = 3 + 3 + 3 + 1 $。
- $11 = 3 + 3 + 3 + 1 + 1 $。
- $12 = 3 + 3 + 3 + 3 $。
- $13 = 3 + 3 + 3 + 3 + 1$。
然而,使用 $5$ 枚 $1$ 分或者 $3$ 分的邮票根本不可能贴出 $14$ 分的邮资。因此,答案为 $13$。
数据规模与约定
对于 $100%$ 的数据,保证 $1 \leq k \leq 200$,$1 \leq n \leq 50$,$1 \leq a_i \leq 10^4$。
说明
题目翻译来自 NOCOW。
题目分析
如果用bfs来做这道题,根据题意,可以将每次拼出的邮资的值看作一个节点
首先给每个节点赋值
点击查看代码
for(int i = 0; i < n; i++){
int next = now + stamp[i]; // 尝试使用第 i 种邮票,得到新邮资
同时确保拼出的值用了最少的张数
点击查看代码
if (sheet[next] > sheet[now] + 1 && sheet[now] + 1 <= k) {
// 确保拼出的邮资用了更少的张数 并且 没有超过k张
sheet[next] = sheet[now] + 1; // 更新拼出 next 的最少邮票数
queue[rear++] = next;
}
题目中要求返回的是连续拼出面值中最大的一个,注意是连续
点击查看代码
//题目要求连续拼出从1到m的邮资并取最大
for (int i = 1; i < MAXN; i++) {
if (sheet[i] > k) {
return i - 1; //返回最大连续的邮资的值
}
}
点击查看代码
#include <stdio.h>
#define MAXN 10000
int sheet[MAXN]; //表示组成面值为m所需的张数
int stamp[52];
int k,n;
int BFS(){
int queue[MAXN];
int front = 0, rear = 0;
queue[rear++] = 0;
sheet[0] = 0;
while(front < rear){
int now = queue[front++]; //当前邮资
for(int i = 0; i < n; i++){
int next = now + stamp[i]; // 尝试使用第 i 种邮票,得到新邮资
if (next >= MAXN)
continue;
if (sheet[next] > sheet[now] + 1 && sheet[now] + 1 <= k) {
// 确保拼出的邮资用了更少的张数 并且 没有超过k张
sheet[next] = sheet[now] + 1; // 更新拼出 next 的最少邮票数
queue[rear++] = next;
}
}
}
//题目要求连续拼出从1到m的邮资并取最大
for (int i = 1; i < MAXN; i++) {
if (sheet[i] > k) {
return i - 1; //返回最大连续的邮资的值
}
}
}
int main() {
scanf("%d %d", &k, &n);
for (int i = 0; i < n; i++) {
scanf("%d", &stamp[i]);
}
for (int i = 0; i < MAXN; i++) {
sheet[i] = 1e9; //初始化的状态数组,足够大的初始值,表示还没有被更新
}
int result = BFS();
printf("%d\n", result);
return 0;
}

浙公网安备 33010602011771号