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

题目

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

描述

“啊…苍穹幕落…怎么又不能用啊…”
正正最近沉迷于毒(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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值