gesp(C++五级)(14)洛谷:B4071:[GESP202412 五级] 武器强化
题目描述
小杨有 n n n 种武器和 m m m 种强化材料。第 i i i 种强化材料会适配第 p i p_i pi 种武器,小杨可以花费 c i c_i ci 金币将该材料对应的适配武器修改为任意武器。
小杨最喜欢第 1 1 1 种武器,因此他希望适配该武器的强化材料种类数严格大于其他的武器,请你帮小杨计算为了满足该条件最少需要花费多少金币。
输入格式
第一行包含两个正整数 n , m n,m n,m,含义如题面所示。
之后 m m m 行,每行包含两个正整数 p i , c i p_i,c_i pi,ci,代表第 $i $ 种强化材料的适配武器和修改花费。
输出格式
输出一个整数,代表能够使适配第 1 1 1 种武器的强化材料种类数严格大于其他的武器最少需要花费的金币。
样例 #1
样例输入 #1
4 4
1 1
2 1
3 1
3 2
样例输出 #1
1
提示
样例解释
花费 1 1 1,将第三种强化材料的适配武器由 3 3 3 改为 1 1 1。此时,武器 1 1 1 有 2 2 2 种强化材料适配,武器 2 2 2 和武器 3 3 3 都各有 1 1 1 种强化材料适配,满足适配第 1 1 1 种武器的强化材料种类数严格大于其他的武器。
数据范围
对于 100 % 100\% 100% 的数据,保证 1 ≤ n , m ≤ 1 000 1\le n,m\le 1\, 000 1≤n,m≤1000, 1 ≤ p i ≤ n 1\le p_i\le n 1≤pi≤n, 1 ≤ c i ≤ 1 0 9 1\le c_i\le 10^9 1≤ci≤109。
子任务编号 | 得分占比 | n n n | m m m |
---|---|---|---|
1 1 1 | 20 % 20\% 20% | ≤ 2 \le 2 ≤2 | ≤ 1 000 \le 1\, 000 ≤1000 |
2 2 2 | 20 % 20\% 20% | ≤ 1 000 \le 1\,000 ≤1000 | ≤ 2 \le 2 ≤2 |
3 3 3 | 60 % 60\% 60% | ≤ 1 000 \le 1\, 000 ≤1000 | ≤ 1 000 \le 1\, 000 ≤1000 |
AC代码(100分)
cpp
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,p,c,ans=1e12+10;
vector<ll> v[1010];//v[i]:存第i种武器的所有修改代价
//函数以t为武器1的目标数
ll f(int t){
ll now=v[1].size();//目前武器1的数量
ll sum=0;//修改代价累加和
vector<int> tmp;//临时动态数组
for(int i=2;i<=n;i++){
ll xg=max((ll)(v[i].size()-t+1),0ll);
for(int j=0;j<=xg-1;j++){
sum+=v[i][j];
}
now+=xg;
for(int j=xg;j<v[i].size();j++){
tmp.push_back(v[i][j]);
}
}
sort(tmp.begin(),tmp.end());
for(int i=0;i<t-now;i++){
sum+=tmp[i];
}
return sum;
}
int main(){
//输入
cin>>n>>m;
for(ll i=1;i<=m;i++){
cin>>p>>c;
v[p].push_back(c);//存第p种武器的所有修改代价
}
//将每个动态数组v[i]中的修改代价升序排序
for(int i=1;i<=n;i++){
sort(v[i].begin(),v[i].end());
}
//暴力枚举找答案:以i为武器1的目标数
for(ll i=max((ll)v[1].size(),1ll);i<=m;i++){
ans=min(ans,f(i));
}
//输出答案
cout<<ans;
return 0;
}
文末彩蛋: