最大数的和——精选推荐

最⼤数的和
题意:有N个数,每次从中任意选取K个数,取其中的最⼤值,求所有组合能取得的最⼤值的
和.N≤100,000,K≤50,输出结果对1000000007取模的结果.0≤每个数≤10^9
样例输⼊1
5 2
1 2 3 4 5
样例输出1
40
样例输⼊2
5 3
电子屏制作1 2 3 4 5
样例输出2
45
分析:很显然,这是⼀道组合数学的题⽬。其实我们只需要求出每个数作为最⼤值出现的次数就能够得到答案.如果⼀个数能够作为最⼤值出现,那么这个数肯定⼤于等于第k⼤的数,先排序.
我们要到当前数作为最⼤数的次数,这由⽐他⼩的数来决定.对于样例2,我们考虑3这个数,将3固定在最⾼位,那么我们还需要确定k-1个数,这k-1个数可以取任意的⽐3⼩的数,例如1,2或2,1两个组合,也就是说如果我们当前考虑的数是第i⼤的数,那么只需要计算出c[i-1][k-1](i-1个数中选k-1个数的⽅案个数)再乘以这个数即可.
挂面纸
然⽽,本题要求取模,不能直接计算组合数,可以使⽤逆元来计算,但是这样有点复杂,如果我们直接递推则可以直接取模(不涉及到除法),这样有⼀个问题:内存占⽤太⼤,这道题⽤long long,开数组内存花费太⼤了,怎么办呢?可以发现递推组合数的时候状态i的结果只与状态i-1的结果有关,所以可以使⽤滚动数组!代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 100010
using namespace std;
miankongqu
const int MOD = 1e9 + 7;
库房管理流程long long p[maxn];
long long f[2][maxn];
long long ans;
int k, n;
void work() {
f[0][0] = 1;碎花刀刀
int i, j;
bool flag = 1;
for (i = 1;i <= n - 1;i++) {
int m = min(i,k-1);
for (j = 0;j <= m;j++) {
if (j == 0 || j == i) f[flag][j] = 1;
else f[flag][j] = (f[!flag][j - 1] + f[!flag][j]) % MOD;            }
立式小便器if (k - 1 <= i)
ans += p[i + 1] * f[flag][k - 1] % MOD;
ans %= MOD;
flag = !flag;
}
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 1;i <= n;i++) scanf("%d", &p[i]);
sort(p + 1, p + 1 + n);
work();
printf("%lld", ans);
return0;
}

本文发布于:2024-09-21 10:33:47,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/276249.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:个数   取模   组合   结果   计算
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议