[GESP202412 五级] 武器强化

题目描述

小杨有 nnn 种武器和 mmm 种强化材料。第 iii 种强化材料会适配第 pip_ipi 种武器,小杨可以花费 cic_ici 金币将该材料对应的适配武器修改为任意武器。

小杨最喜欢第 111 种武器,因此他希望适配该武器的强化材料种类数严格大于其他的武器,请你帮小杨计算为了满足该条件最少需要花费多少金币。

输入格式

第一行包含两个正整数 n,mn,mn,m,含义如题面所示。

之后 mmm 行,每行包含两个正整数 pi,cip_i,c_ipi,ci,代表第 $i $ 种强化材料的适配武器和修改花费。

输出格式

输出一个整数,代表能够使适配第 111 种武器的强化材料种类数严格大于其他的武器最少需要花费的金币。

样例 #1

样例输入 #1

4 4
1 1
2 1
3 1
3 2

样例输出 #1

1

提示

样例解释

花费 111,将第三种强化材料的适配武器由 333 改为 111。此时,武器 111222 种强化材料适配,武器 222 和武器 333 都各有 111 种强化材料适配,满足适配第 111 种武器的强化材料种类数严格大于其他的武器。

数据范围

对于 100%100\%100% 的数据,保证 1≤n,m≤1 0001\le n,m\le 1\, 0001n,m10001≤pi≤n1\le p_i\le n1pin1≤ci≤1091\le c_i\le 10^91ci109

子任务编号 得分占比 nnn mmm
111 20%20\%20% ≤2\le 22 ≤1 000\le 1\, 0001000
222 20%20\%20% ≤1 000\le 1\,0001000 ≤2\le 22
333 60%60\%60% ≤1 000\le 1\, 0001000 ≤1 000\le 1\, 0001000

解析

枚举将武器一的材料变成i所需要的最小花费,再这些最小花费中找到最小值即为答案,详见代码:

#include<bits/stdc++.h>
using namespace std;
int n, m;
vector <int> c[1005];//c[i][j]表示可以强化第i种武器的材料,修改花费
long long ans = 9e18;
int main() {
    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        int p, cc;
        cin >> p >> cc;
        c[p].push_back(cc);
    }
    for(int i = 1; i <= n; i++) {//所有材料
        sort(c[i].begin(), c[i].end());//按花费从小到大排序
    }
    int a1 = c[1].size(); //可提升第一种武器的材料数
    for(int i = a1; i <= m; i++) {//枚举将武器一提升到i个材料所需的最小花费
        long long sum = 0;//最小花费
        long long sumcnt = 0; //在削弱其他武器的材料的时候,第一种武器的材料可以增加多少
        vector <int> tmp;//未修改的材料
        for(int j = 2; j <= n; j++) {//从第二种武器开始
            if (c[j].size() > i) {//如果超过i个材料
                int cnt = c[j].size() - i;//修改材料的数量
                for(int k = 0; k < cnt; k++) {//循环计算修改金额
                    sum += c[j][k];
                }
                for(int k = cnt; k < c[j].size(); k++) {//剩下的加入未修改材料
                    tmp.push_back(c[j][k]);
                }
                sumcnt += cnt;
            } else {//如果没超过i
                for(int k = 0; k < c[j].size(); k++) {//都加入未修改材料
                    tmp.push_back(c[j][k]);
                }
            }
            if (a1 + sumcnt < i) {//如果修改数量不足以让第一种武器的材料数量达到i
                sort(tmp.begin(), tmp.end());//将未修改材料从小到大排序
                for(int k = 0; k < i - a1 - sumcnt; k++) {//从最小的花费开始修改
                    sum += tmp[k];
                }
            }
        }
        ans = min(ans, sum);//取最小值
    }
    cout << ans;
    return 0;
}
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐