当前位置: 首页 > news >正文

洛谷 B4071 [GESP202412 五级] 武器强化


思考难度低,但是代码难度相对较高的题,故做个记录。

首先,题目说了要花费最少的钱,所以我们每次拿最便宜的材料给武器1

思想:每次都拿最便宜的材料

然后考虑一下这个思想是否正确,找一下反例,每次拿一个材料给武器1,可以让他增加一个。

那很明显,如果我们除了武器1之外的,最多的那个材料,不管他的价格是多少,拿掉他,给武器1,相当于直接让武器增加了2个材料(此消彼长)

所以有没有一种可能,拿两次最便宜的材料,不如拿一个材料种类最多的武器?

可以举出一个反例:3 3/ 4,3+3块钱贡献了2个,4块钱也贡献了2个,显然我们的核心思想需要改变。

改进思想:每次都拿最便宜的材料

1、如果此材料在 武器.材料种类 最多的武器上,直接执行

最便宜的1次操作实现了2次贡献,很显然已经没有收益更高的操作了,这一步没问题

2、如果此材料不在 武器.材料种类 最多的武器上;考虑对比 武器.材料种类 最多的武器

前者操作:令最便宜的花费为 cheapst,对武器1的贡献 是1,每单位贡献花费cheapst

后者操作:设花费为k(武器.材料种类 最多的武器可能有多个,所以这一步也要拿这些武器中最便宜的材料),对武器1的贡献 是2,每单位贡献花费 k/2

所以需要对比这两者哪个更加划算,由于k/2可能需要浮点数很麻烦,对比的时候直接把cheapst*2就可以。

显然,已经找不出来更划算的操作了,易得这一步也是没问题的。

根据思想来实现全部功能,思想其实很容易定下来,但是这代码就相当难写了,AC代码如下所示。

#include <bits/stdc++.h>
#define int long long
#define per(i,j,k) for(int (i)=(j);(i)<=(k);++(i))
#define rep(i,j,k) for(int (i)=(j);(i)>=(k);--(i))
#define fr first
#define se second
#define endl '\n'
using namespace std;const int N=1006;int n,m,ans;
int p[N],c[N];struct Material {int idx;int adapt;int cost;
}mat[N];
struct matCMP{bool operator()(Material a,Material b) {if (a.cost==b.cost) {return a.idx<b.idx;}return a.cost<b.cost;}
};
struct Weapon{int idx;set<Material,matCMP>mat;
}wea[N];//返回 武器.材料种类最多的 所有武器(除了武器1)
vector<Weapon>f() {int cnt=0;per(i,2,n) {cnt=max(cnt,(int)wea[i].mat.size());}vector<Weapon>res;per(i,2,n) {if (wea[i].mat.size()==cnt) {res.push_back(wea[i]);}}return res;
}
//返回最便宜的材料价格(除了武器1)
int g() {int res=INT_MAX;per(i,2,n) {if (wea[i].mat.size()) {res=min(res,(*wea[i].mat.begin()).cost);}}return res;
}
bool act1() {//最便宜的材料在 武器.材料种类最多的 武器上//直接执行vector<Weapon>v=f();int cheapst=g();per(i,0,v.size()-1) {if (v[i].mat.size()) {int val=(*v[i].mat.begin()).cost;if (val==cheapst) {wea[1].mat.insert(*v[i].mat.begin());wea[v[i].idx].mat.erase(wea[v[i].idx].mat.begin());ans+=val;return true;}}}return false;
}
void act2() {//cheap得到1贡献  ~  约等于 2*chep得到2贡献//武器.材料种类最多的 武器上,k得到2贡献int cheap=g()*2;vector<Weapon>v=f();bool flag=false;//不拿最便宜的更划算int idx=-1;per(i,0,v.size()-1) {if (v[i].mat.size()) {if ((*v[i].mat.begin()).cost<cheap) {if (flag==false) {flag=true;idx=i;}else {if ((*v[i].mat.begin()).cost<(*v[idx].mat.begin()).cost)idx=i;}}}}if (flag) {//拿v[idx]的最便宜材料wea[1].mat.insert(*v[idx].mat.begin());wea[v[idx].idx].mat.erase(wea[v[idx].idx].mat.begin());ans+=(*v[idx].mat.begin()).cost;}else {//拿最便宜的材料cheap>>=1;ans+=cheap;per(i,2,n) {if (wea[i].mat.size()) {if ((*wea[i].mat.begin()).cost==cheap) {wea[1].mat.insert(*wea[i].mat.begin());wea[i].mat.erase(wea[i].mat.begin());break;}}}}
}void solve() {cin>>n>>m;per(i,1,n)wea[i].idx=i;per(i,1,m) {cin>>p[i]>>c[i];mat[i].idx=i;mat[i].adapt=p[i];mat[i].cost=c[i];wea[p[i]].mat.insert(mat[i]);}if (n==1) {cout<<0<<endl;return;}while (wea[1].mat.size()<=f()[0].mat.size()) {if (!act1())act2();}cout<<ans<<endl;
}signed main() {ios::sync_with_stdio(false), cin.tie(nullptr);int t = 1;while (t--)solve();return 0;
}

不仅如此,还有两个注意点

1、因为n>=1,所以n=1的时候,不需要任何操作,直接输出0

2、自定义容器排序,set里面,如果只用 a.cost<b.cost,那么set保持升序的时候a.cost==b.cost会被直接去重,需要让他们cost相等时,按照永远不会相等的值来排序,或者直接用multiset

个人认为,思维难度大概,代码难度至少

观察发现,数据范围相当小,更进一步从贡献角度考虑,每次操作,我们去计算材料对武器1的 每单位贡献花费,枚举所有材料就可以了,此时他就是一个完美的


文章转载自:

http://dQX5oRyh.kgfsz.cn
http://CGF9G04A.kgfsz.cn
http://aKFc6Ki2.kgfsz.cn
http://gzgilWXn.kgfsz.cn
http://rYLATe51.kgfsz.cn
http://gsmBIiwD.kgfsz.cn
http://GIUx2M8C.kgfsz.cn
http://ilYhCpoJ.kgfsz.cn
http://lYMwhBPT.kgfsz.cn
http://umA0OEaa.kgfsz.cn
http://OExG155h.kgfsz.cn
http://ieGvUkqg.kgfsz.cn
http://6hOdlc1z.kgfsz.cn
http://k7MeB2No.kgfsz.cn
http://uJfB7GmG.kgfsz.cn
http://4Bv2SzlE.kgfsz.cn
http://xnYHc0Ue.kgfsz.cn
http://AHMjxxi5.kgfsz.cn
http://C7EbIHhD.kgfsz.cn
http://AOUNjoT9.kgfsz.cn
http://U9s0SHs3.kgfsz.cn
http://KuWw6iSX.kgfsz.cn
http://ye08Hao3.kgfsz.cn
http://g20XlqGw.kgfsz.cn
http://MIrvg9ku.kgfsz.cn
http://VoIpqhIH.kgfsz.cn
http://FlNnF8Lh.kgfsz.cn
http://uW2H6qWp.kgfsz.cn
http://VzaSo7uX.kgfsz.cn
http://KcB0iAeZ.kgfsz.cn
http://www.dtcms.com/a/372509.html

相关文章:

  • 0. 系统架构设计师考试大纲核心内容速览
  • [C/C++学习] 6.弹跳小球(B)
  • Easysearch 证书:Windows 上创建自签名证书的 7 种方法
  • Kafka基础理论
  • JavaScript 设计模式概览
  • Jenkins与Kubernetes集成部署流水线
  • arduino uno小车开发接线与程序记录
  • 【LeetCode 热题 100】128. 最长连续序列
  • 在object-c中方法多个参数怎么接收?
  • 蓓韵安禧DHA高含量好吸收特性深度解析
  • Pandas 合并数据集:merge 和 join
  • DINOv3 新颖角度解释
  • leetcode219.存在重复元素
  • 卷积神经网络CNN-part4-VGG
  • 【图像处理基石】图像处理中的边缘检测算法及应用场景
  • 项目中缓存雪崩,击穿,穿透的应对方法
  • AI推介-多模态视觉语言模型VLMs论文速览(arXiv方向):2025.06.10-2025.06.15
  • struct结构体内存对齐详解
  • 使用QLoRA 量化低秩适配微调大模型介绍篇
  • 变量与常量
  • 第7.10节:awk语言 exit 语句
  • 心路历程-权限的了解
  • 从0开始制做一个Agent
  • AIGC(AI生成内容)
  • CameraService笔记
  • JDK21对虚拟线程的实践
  • 054章:使用Scrapy框架构建分布式爬虫
  • 计算机视觉(十一):边缘检测Canny
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘wheel’问题
  • 监控系统 | 脚本案例