[陕师大校赛] A 正正的毒奶粉

    xiaoxiao2023-11-20  176

    题目

    前言: 没有传送门, 由于出题人的题解有问题, 所以当时的题的数据也可能有问题, 也就是说他们可能还欠我一个气球 -_-

    描述

    “啊…苍穹幕落…怎么又不能用啊…” 正正最近沉迷于毒(D)奶(N)粉(F)不能自拔, 每天熬夜刷装备已经让正正有了双大大的黑眼圈, 但是正正是一个菜鸡, 他甚至搞不清自己的战斗力是怎么计算的, 为了清楚的知道自己的战斗力, 他特地的请教大佬得知: 每件装备战斗力 = = =(1+白字属性值)*(1+黄字属性值)*装备基础分 总战斗力 = = = ∑ \sum 每件装备战斗力 现在有 n n n件装备, 但是只能从其中选 m m m件, 在你选择的 m m m件装备中, 白字属性值每件装备都可以生效, 黄字属性值只有一件装备可以生效, 现在让你帮帮正正, 怎么样选才能让正正战斗力最高

    输入

    第一行有两个数 n n n, m m m( 1 ≤ m ≤ n ≤ 10000 1 \leq m \leq n \leq 10000 1mn10000)表示装备的总数和正正可以选择的装备数. 之后每行有3个数, v v v, p p p, q q q( 0 ≤ v ≤ 10000 , 0 ≤ p , q ≤ 5 0 \leq v \leq 10000, 0 \leq p, q \leq 5 0v10000,0p,q5)分别表示每件装备的基础分, 白字属性值, 黄字属性值

    输出

    一个数表示最终的战斗力, 答案保留2位小数

    样例输入

    5 2 100 0.3 0.1 80 0.5 0.2 200 0.2 0.4 100 0.4 0.3 50 0.3 0.6

    样例输出

    476.00

    解决

    分析

    仔细查看公式与题目描述, 白字属性值是每件装备都可以生效的, 所以在每件装备的战斗力中可以直接使用 (1+白字)*装备基础分, 而对于唯一一件生效的黄字, 可以写成 (1+白字)*装备基础分 + (1+白字)*黄字*装备基础分 , 当所有的装备加起来的时候, 也就是看哪一件装备的黄字生效时附加战斗力最高, 即 (1+白字)*黄字*装备基础分 这一部分最大

    设计

    创建一个结构体, 两个属性, 基础战斗力 (1+白字)*装备基础分, 加成比率 黄字, 然后按照基础战斗力从大到小进行排序, 由于加成值最大的装备, 可能初始基础战斗力低, 还不如选择一个高基础战斗力的装备, 之后随便一件装备加成一下都比选择加成值最大的战斗力强. 所以分成两种情况, 第一种情况, 基础战斗力优先, 从排序后的装备里, 取出前m个装备, 在他们中找出加成最大的, 使它的黄字生效, 得到一个战斗力; 第二种情况, 加成值优先, 从排序后的装备里, 取出前m-1个装备, 他们的基础战斗力是最高的, 然后在剩余的所有的装备中计算加成值和基础战斗力组合最高的, 将那个装备的黄字生效并且将其战斗力加上去.(如果是在所有装备中计算加成值最高的, 如果在前m-1个里面, 那么为了最大提升战斗力, 必然选择第m件装备, 就与第一种情况相同了), 然后输出两个中最大的战斗力即可

    编码

    #include <bits/stdc++.h> using namespace std; #define MAX 10005 struct Zhuang_bei { float ji_chu_zhan_dou_li; float jia_cheng; }; bool zhuang_bei_compare(const Zhuang_bei & z1, const Zhuang_bei & z2) { return z1.ji_chu_zhan_dou_li > z2.ji_chu_zhan_dou_li; } Zhuang_bei zhuang_bei[MAX]; int main(void) { int n, m; float v, p, q; int i, j, k; cin >> n >> m; for (i = 0; i < n; i++) { cin >> v >> p >> q; zhuang_bei[i].ji_chu_zhan_dou_li = v * (1 + p); zhuang_bei[i].jia_cheng = q; } sort(zhuang_bei, zhuang_bei + n, zhuang_bei_compare); // 1. 基础战斗力优先 float max1 = 0, zui_da_jia_cheng = 0; for (i = 0; i < m; i++) { max1 += zhuang_bei[i].ji_chu_zhan_dou_li; zui_da_jia_cheng = max(zui_da_jia_cheng, zhuang_bei[i].ji_chu_zhan_dou_li * zhuang_bei[i].jia_cheng); } max1 += zui_da_jia_cheng; // 2. 加成值优先 float max2 = 0; zui_da_jia_cheng = 0; for (i = 0; i < m - 1; i++) { max2 += zhuang_bei[i].ji_chu_zhan_dou_li; } for (i = m - 1; i < n; i++) { zui_da_jia_cheng = max(zui_da_jia_cheng, zhuang_bei[i].ji_chu_zhan_dou_li * (1 + zhuang_bei[i].jia_cheng)); } max2 += zui_da_jia_cheng; printf("%.2f\n", max1 > max2 ? max1 : max2); }

    结果

    未知…

    总结

    学习如何简化问题

    最新回复(0)