弹钢琴
来源:互联网 发布:软件编程技术培训 编辑:程序博客网 时间:2024/04/30 23:49
题目描述
Flsy的妈妈出去买菜了,他让Flsy在家里好好练习弹钢琴。小C的钢琴很奇怪,一共有N个琴键,每一个琴键有一个价值Ai。当Flsy弹钢琴时,他会同时按住K个不同的琴键,但是只有价值最大的琴键会发出声音。Flsy想练习所有不同的按键组合,那么他能弹奏出声音的琴键的价值之和(同一个琴键在不同的组合中被弹出声音需要重复计算),最终的答案对1e9+7取模。
输入
输入第一行,两个整数N和K。 输入第二行,N个整数Ai。
输出
输出仅一行,为题目中的答案。
题目分析:
关键字:组合数(数学),乘法逆元,DP,终态枚举
题目的想法很直接,就是先按琴键的值排序,终态枚举每个琴键,使之的值为最大值,从前面的数中去k-1个排列组合加在ans上即可。
其实就是求排列组合的裸题,数据相对也不算很大,可以之间递推得到,其实差不多算是DP的一个前身,还有就是乘法逆元,下面将一一讲解。
首先是递推:
类似于DP,定义数组C[i][j]表示从i中取出j个数的方案数
发现组合数可以转移:C[i][j]=C[i-1][j-1]+C[i-1][j];
就可以每次把上一层的组合数都转移过来即可,代码如下:
#include<cstdio>#include<algorithm>using namespace std;#define N_MAX 100005#define MOD 1000000007int n,k,ans;int dp[N_MAX][55],A[N_MAX];int main(){ scanf("%d %d",&n,&k); for(int i=1; i<=n; i++) scanf("%d",&A[i]); sort(A+1,A+1+n); dp[0][0]=1; for(int i=1; i<=n; i++) { for(int j=1; j<=k; j++) dp[i][j]=(dp[i-1][j-1]+dp[i-1][j])%MOD; ans=(ans+1LL*dp[i][k]*A[i])%MOD; } printf("%d\n",ans); return 0;}
接下来是乘法逆元(乘法逆元是怎么来的呢?这里不解释,直接运用,之后可能写一个关于乘法逆元的专题)
组合数与乘法逆元相组合可以得到以下的公式:
C(i,j)=i! * ((i-j)!)^(MOD-2) * (j!)^(MOD-2) (这里对MOD也是有要求的,应该是质数,10^9+7显然是质数,所以MOD可以这么用)
发现本题还要更特殊一点,因为发现求组合数时k-1是不变的,所以就可以简化上述公式为C[i][j]=C[i-1][j]a (a-b)^(MOD-2)(还不会私我……)
代码如下:
#include<bits/stdc++.h>using namespace std;#define K_MAX 55#define N_MAX 100005#define MOD 1000000007#define LL long long/* 求组合数C[i][k-1] | n>=i>=k-1 乘法逆元:F[i][j]=F[i-1][j]*a*(a-b)^(MOD-2); */int A[N_MAX];LL dp[N_MAX][55];int n,k,ans;void add(int &a,LL b) { b%=MOD; a+=b; if(a>=MOD) a-=MOD;}int fst(int x,int n) {//快速幂 int res=1; while(n) { if(n&1) { res=(1LL*res*x)%MOD; } x=(1LL*x*x)%MOD; n>>=1; } return res;}void deal(int a,int b) {//得出dp[i][j] if(a==b){ dp[a][b]=1; return; } int res=fst(a-b,MOD-2); dp[a][b]=(1LL*dp[a-1][b]*a)%MOD; dp[a][b]=(1LL*dp[a][b]*res)%MOD;}int main() { scanf("%d %d",&n,&k); for(int i=1; i<=n; i++) scanf("%d",&A[i]); sort(A+1,A+1+n); for(int i=k; i<=n; i++) { deal(i-1,k-1); add(ans,1LL*dp[i-1][k-1]*A[i]); } printf("%d\n",ans); return 0;}
WA:带模运算的组合数是不可以用除的,因为模了后不一定除得尽。
- 弹钢琴
- 弹钢琴
- 自己弹钢琴
- 要学会双手弹钢琴
- 弹钢琴flash游戏
- 大家进来弹钢琴啦!~
- C# 弹钢琴程序
- 弹钢琴的码农
- Android-简易版弹钢琴
- 有人说"编程就弹钢琴一样"
- 啊!geek:用6个iPhone弹钢琴
- C版弹钢琴程序进化版——Key下落效果
- 孙宇:机器人弹钢琴不算啥,能教它不“碎蛋”才是真炫酷
- 20171008ElasticSearch学习总结
- [编程题] 数字翻转
- CSS3动画
- Java代码性能优化
- linux ubuntu 16.04下deb文件的安装和一些问题的解决
- 弹钢琴
- 自定义View之滑动解锁
- Android中shape中的属性大全
- 1002. 写出这个数
- oracle二次开发调用外部C函数。
- 【南阳理工】 108 士兵杀敌(一)
- iOS-XML文件解析(原生NSXMLParser和GDataXML两种解析方式)
- 前端_抽 奖
- 定时函数