NOIP 模拟6 T3
前言:
对于T1辣鸡(25pts)的感想:问题在于数据范围分析与情况枚举的全面性,int改为long long(85pts),考虑坐标相等情况(AC)
然而调试却将近一下午,问题在于仍然单纯模拟分析代码而没有实际输出参数去检验错误,这样效率会低很多
进入正题:
分析题目:经过多次测试 多少对于题目类型有一定分析能力
首先 题目要求求出大佬劳累值期望,那么根据题中给出的信息,劳累值显然是区间最大难度的映射,而问题就转化为求区间[1,n]内,所有区间长度不小于k的区间的最大劳累值之和
有一个技巧,概率期望类型题若出现取模,则必然不是单纯的概率期望,因为小数显然无法进行取模运算,也就是说题中所有答案必然可以表示为最简分数形式
而求最简分数显然是要将分子分母分离运算,也就是说这道题本质上其实并不是一道概率期望类型题
考虑期望定义,我们本质上是求每种最大劳累值方案数比总数乘以其对应劳累值之和,这显然是一道组合数学题
分析对于区间[1,n]内每个点劳累值显然是随机等可能的也就是说只要能解决对于一个区间最大值的求取,那么问题就迎刃而解
那么求解如下:
首先要明确本题的模型是可重复排列(根据样例与题干 对于每道题其劳累度的选择空间互相平行)
那么假设我们选取i为区间t的最大值,首先对于i的摆放有C(k,p)种可能(1<=p<=k)(这是阶段一)
接着我们再假设在区间t中摆放了p个i,那么为了使i成为最大值 剩余位置只能选择小于i的数进行补全
(关键点)根据之前分析的可重复排列模型,问题最终抽象为从i-1个数中选择k-p个来填满剩下的位置,显然方案数为(i-1)^(k-p);
最终我们可以的出区间t内劳累度最大值的计算公式为∑C(k,p)*(i-1)^(k-p),最终再乘上对应权值w即可
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define I int 4 #define D double 5 #define LL long long 6 #define UL unsigned long long 7 #define B bool 8 #define C char 9 #define RE register 10 #define V void 11 #define L inline 12 const I mod = 1e9 + 7; 13 const I MAXN = 1010; 14 const I MAXM = 1010; 15 I n,m,k,w[MAXM]; 16 LL sw,sigma1,sigma2,t,j[MAXM],y[MAXM]; 17 L I read(); L LL qpow(I,I); L LL Z(I,I); 18 signed main(){ 19 n = read(); m = read(); k = read(); 20 21 j[1] = 1; y[1] = 1; 22 for(RE I i(2);i <= 1000; ++ i){ 23 j[i] = j[i - 1] * i % mod; 24 y[i] = qpow(j[i],mod - 2); 25 } 26 for(RE I i(1);i <= m; ++ i) w[i] = read(); 27 if(k > n){ printf("0"); return 0; } 28 for(RE I i(1);i <= m; ++ i){ sw = 0; 29 for(RE I p(1);p <= k; ++ p) 30 sw = (sw + Z(k,p) * qpow(i - 1,k - p) % mod) % mod; 31 sigma2 = (sigma2 + sw * w[i]) % mod; 32 } 33 sigma1 = qpow(m,k); 34 t = qpow(sigma1,mod - 2); 35 printf("%lld",sigma2 * t % mod * (n - k + 1) % mod); 36 } 37 L I read(){ RE I x(0);RE C z=getchar();while(!isdigit(z))z=getchar();while(isdigit(z))x=(x<<3)+(x<<1)+(z^48),z=getchar();return x; } 38 L LL qpow(I a,I b){ 39 LL res(1),base(a); 40 while(b){ 41 if(b & 1) res = res * base % mod; 42 base = base * base % mod; 43 b >>= 1; 44 }return res; 45 } 46 L LL Z(I a,I b) { if(a == b || b == 0) return 1; return j[a] * y[a - b] % mod * y[b] % mod ; }
总结:本次模拟考的爆点在于数据范围分析,情况枚举的全面性以及数学模型的判断(由于将可重复排列判断为不可重复排列95pts->25pts)