题目链接:https://ac.nowcoder.com/acm/problem/212913
到主站看:https://blog.csdn.net/weixin_43346722/article/details/109226431
题目
公司中总共有 个人,其中第
个人的初始工资为
。公司根据每个人的绩效(工作表现)来评定每个人的涨薪幅度。每年有
个人绩效为 A,工资可以变为原来的
倍;
个人绩效为 B,工资可以变为原来的
倍,其余人绩效为 C,工资不变,连续两年绩效为 C 会被开除。(保证
)
假如公司没有一直招聘新员工,请问 年后,公司需要给所有在职员工支付的工资总和最多为多少。由于答案可能很大,请输出对
取模后的结果。
输入
输入第一行包含四个正整数 ,意义如题面所示。
接下来一行包含 个正整数,第
个正整数为
代表第
个人的初始工资。
输出
输出一行一个整数表示 年后工资总和对
取模后的结果。
样例输入1
2 1 1 1 5 3
样例输出1
21
样例输入2
2 2 0 0 5 2
样例输出2
0
数据范围
对于 的数据范围,满足
对于 的数据范围,满足
对于另外 的数据范围,满足 满足
且
对于另外 的数据范围,满足 满足
且
对于 的数据范围,满足
思路
这道题是一道贪心。
我们可以发现,我们一直把 A 给初始值最大的那些人,把 B 给初始值接着大的人是最优的。
至于别的人,被开除也无所谓(好惨
求 A 类人和 B 类人的贡献就先用快速幂求出每类人增长的倍数,然后乘上去即可。
有一个细节,就是如果年数小于 年的话 C 类人不会被开除,就还要算上它们的。
比赛时
看出来了,就码出来了。
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
#define mo 1000000007
using namespace std;
ll n, m, x, y, a[100001], Asum, Bsum, Esum, mi3, mi2, re, ***;
char c;
ll read() {
re = 0;
*** = 1;
c = getchar();
while ((c < '0' || c > '9') && c != '-') c = getchar();
if (c == '-') {
*** = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
re = re * 10 + c - '0';
c = getchar();
}
return re * ***;
}
bool cmp(ll x, ll y) {
return x > y;
}
ll ksm(ll x, ll y) {//快速幂
re = 1;
while (y) {
if (y & 1) re = (re * x) % mo;
x = (x * x) % mo;
y >>= 1;
}
return re;
}
int main() {
n = read();
m = read();
x = read();
y = read();
for (ll i = 1; i <= n; i++) a[i] = read();
mi3 = ksm(3, m);//预处理出翻的倍数
mi2 = ksm(2, m);
sort(a + 1, a + n + 1, cmp);//从大到小排序
for (ll i = 1; i <= x; i++)//最前面的(最大的)绩效为 A
Asum = (Asum + (a[i] * mi3) % mo) % mo;
for (ll i = x + 1; i <= x + y; i++)//接着(接着大的)就是绩效为 B
Bsum = (Bsum + (a[i] * mi2) % mo) % mo;
if (m < 2)//只有年数小于两年,这些 C 的才不会被开除,才要记录
for (ll i = x + y + 1; i <= n; i++)
Esum = (Esum + (a[i] * m) % mo) % mo;
printf("%lld", (Asum + Bsum + Esum) % mo);
return 0;
} 
京公网安备 11010502036488号