USACO历年青铜组真题解析 | 2023年1月Air Cownditioning II

学习C++从娃娃抓起!记录下USACO(美国信息学奥赛)备考青铜组别比赛学习过程中的题目,记录每一个瞬间。

附上汇总贴:USACO历年青铜组真题解析 | 汇总-CSDN博客


【题目描述】

农夫约翰的 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) 行,每行三个整数,分别为 siti 和 ci 。

第 (N+2) 至 (M+N+1) 行,每行四个整数, 分别为 aibipi 和 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

猜你喜欢

转载自blog.csdn.net/guolianggsta/article/details/134837115
今日推荐