欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!
专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。
适合人群:
- 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
- 希望系统学习C++/Python编程的初学者
- 想要提升算法与编程能力的编程爱好者
附上汇总贴:USACO历年青铜组真题解析 | 汇总-优快云博客
【题目描述】
农夫约翰的 N 头奶牛 (1≤N≤20) 住在一个谷仓里,谷仓里有连续的牛栏,编号为 1−100 。 奶牛 i 占据了编号 [si,ti] 的牛栏。 不同奶牛占据的牛栏范围是互不相交的。 奶牛有不同的冷却要求,奶牛 i 占用的每个牛栏的温度必须至少降低 ci 单位。
谷仓包含 M 台空调,标记为 1−M (1≤M≤10)。第 i 台空调需要花费 mi 单位的金钱来运行 (1≤mi≤1000) ,如果运行,第 i 台空调将牛栏 [ai,bi] 所有牛栏的温度降低 pi (1≤pi≤10^6)。 空调覆盖的牛栏范围可能会重叠。
请帮助农夫约翰求出满足所有奶牛需求要花费的最少金钱。
【输入】
第一行两个整数,分别为 N 和 M。
第 2 至 (N+1) 行,每行三个整数,分别为 si、ti 和 ci 。
第 (N+2) 至 (M+N+1) 行,每行四个整数, 分别为 ai、bi、pi 和 mi。
【输出】
一个整数,表示最少花费的金钱。
【输入样例】
2 4
1 5 2
7 9 3
2 9 2 3
1 6 2 8
1 2 4 2
6 9 1 5
【输出样例】
10
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int n, M;
int fence[105], fence2[105]={0}; // 定义fence记录奶牛需要的每个牛栏的温度,定义fence2记录每台空调开启后每个牛栏的温度
struct air {
int a, b, p, m;
}a[15];
int book[15] = {0}, ans=1e9;
void dfs(int step)
{
memset(fence2, 0, sizeof(fence2)); // 初始化fence2数组
int sum = 0; // 定义sum,记录开启空调后的花费,每次初始化为0
for (int i=1; i<=M; i++) { // 遍历M台空调
if (book[i]==1) { // 对于选中的那些空调
for (int j=a[i].a; j<=a[i].b; j++) { // 将每台空调对应的牛栏温度进行累加
fence2[j]+=a[i].p;
}
sum += a[i].m; // 并将这些空调运行所需的金钱相加
}
}
int tot=0; // 定义tot统计多少个牛栏已经满足温度降低(这里是提升)要求
for (int i=1; i<=100; i++) { // 遍历所有牛栏
if (fence2[i]<fence[i]) break; // dfs剪枝操作,如果某个位置牛栏上升温度低于要求,直接退出
else tot++; // 否则对这个牛栏进行计数
}
if (tot==100) { // 如果满足要求,应该100个牛栏都满足要求
ans = min(ans, sum); // 此时计算花费最少的金钱
return; // 退出这轮搜索
}
for (int i=1; i<=M; i++) { // dfs的深搜过程,遍历M个空调
if (book[i]==0) { // 对于没有被选中的空调
book[i] = 1; // 选中它
dfs(step+1); // 进行下一步计算
book[i] = 0; // 退回时还原现场
}
}
}
int main()
{
cin >> n >> M; // 输入n和M(因为M与后面的m同名,所以这里用大写)
for (int i=1; i<=n; i++) { // 遍历n行
int s, t, c;
cin >> s >> t >> c; // 输入s、t和c
for (int j=s; j<=t; j++) { // 在数轴上将每个位置的值修改为c
fence[j] = c;
}
}
for (int i=1; i<=M; i++) { // 遍历m行
cin >> a[i].a >> a[i].b >> a[i].p >> a[i].m; // 输入每台空调的a、b、p和m
}
dfs(1); // 开始dfs搜索(这里是0还是1开始没有关系,因为定义了book列表来记录某台空调是否被选中)
cout << ans << endl;
return 0;
}
【运行结果】
2 4
1 5 2
7 9 3
2 9 2 3
1 6 2 8
1 2 4 2
6 9 1 5
10