【题解】2019,4.20模拟赛 (白鼠)

\(Description:\)

给出一块巧克力,横着可以切 \(h\) 刀,竖着可以切 \(w\) 刀,横着切了 \(i\) ,竖着切了 \(j\) 可以得到 \((i+1)*(j+1)\) 块巧克力,每次切得代价是巧克力块数,求切 \(k\) 的期望代价,每次在剩余能切的位置等概率选一个切,答案对 \(10^9+7\) 取模。

\(Sample\) \(Input:\)

2 1 2

\(Sample\) \(Output:\)

666666677

$Solution: $

一开始考试的时候没啥子想法,瞎写了一个dp ,状态定的不错,只可惜忘记了他每次的概率也会变换,是要顺便在记一个概率的。。。

\(Sol_1:\)

正解有一种dp,跟我想法差不多:

记 \(f[i][j]\) 表示总共切了 \(i\) 刀,横着切了 \(j\) 刀的概率

再记一个 \(g[i][j]\) 表示总共切 $ i $ 刀,横着切了 \(j\) 刀的期望。

\(Sol_2:\)

直接暴力处理出两个数组,一个是总方案数,另一个记总代价。

最后两者直接除一除。

注意逆元和切得位置不同,切得顺序不同都算不同方案。

我只写了第二种方法,代码短,好理解。

#include<cstdio>
#include<iostream>
#define int long long
using namespace std;
int h,w,k,ans,sum;
const int N=5000+5,p=1e9+7;
int f[N][N],g[N][N];
inline int power(int a,int b){
    int ret=1;
    while(b){
        if(b&1) ret=(ret*a)%p;
        a=(a*a)%p;
        b>>=1;
    }
    return ret;
}
signed main(){
    scanf("%lld%lld%lld",&h,&w,&k);
    g[0][0]=1;
    for(int i=1;i<=min(h,k);++i){
        g[i][0]=g[i-1][0]*(h-i+1)%p;
        f[i][0]=f[i-1][0]*(h-i+1)%p;
        f[i][0]=(f[i][0]+(i+1)*g[i][0]%p)%p;
    }
    for(int j=1;j<=min(w,k);++j){
        g[0][j]=g[0][j-1]*(w-j+1)%p;
        f[0][j]=f[0][j-1]*(w-j+1)%p;
        f[0][j]=(f[0][j]+(j+1)*g[0][j]%p)%p;
    }
    for(int i=1;i<=min(h,k);++i) for(int j=1;j<=min(w,k-i);++j){
        g[i][j]=(g[i][j]+g[i-1][j]*(h-i+1)%p)%p;
        g[i][j]=(g[i][j]+g[i][j-1]*(w-j+1)%p)%p;
        f[i][j]=(i+1)*(j+1)%p*g[i][j]%p;
        f[i][j]=(f[i][j]+f[i-1][j]*(h-i+1)%p)%p;
        f[i][j]=(f[i][j]+f[i][j-1]*(w-j+1)%p)%p;
    }
    for(int i=0;i<=h;++i) if(k-i<=w)
        ans=(ans+f[i][k-i])%p,sum=(sum+g[i][k-i])%p;
    printf("%lld\n",ans*power(sum,p-2)%p);
    return 0;
}

原文地址:https://www.cnblogs.com/JCNL666/p/10744971.html

时间: 2024-07-29 22:19:28

【题解】2019,4.20模拟赛 (白鼠)的相关文章

2019.7.20模拟赛

T1 串 签到题.看完样例就很容易猜到这题答案多半就是\(\{-1,1,2\}\)里面的,然后感性理解理性证明了一通,发现好像的确是这样. 如果串形如\(aaaaaaa,aaaabaaaa,abababababa\),那么直接无解. 如果串不是回文串,就是1. 剩下的全都是2. T2 变量 不算难的最小割,不过我网络流实在太差,只有在省选前补了一下,所以并没有做出来. 首先把\(w_i,|w_i-w_j|\)的系数全都整理出来.既然每个点只能有两种选择,所以考虑最小割,设连\(S\)表示选正权值

题解 【重庆八中模拟赛】寻找代表元

[重庆八中模拟赛]寻找代表元 Description 八中一共有n个社团,分别用1到n编号.八中一共有m个人,分别用1到m编号.每个人可以参加一个或多个社团,也可以不参加任何社团.每个社团都需要选一个代表.我们希望更多的人能够成为代表.这里,每个人至多代表一个社团且每个社团至多有一个代表. Input 第一行输入两个数n和m.以下n行每行若干个数,这些数都是不超过m的正整数.其中第i行的数表示社团i的全部成员.每行用一个0结束. Output 输出最多的能够成为代表的人数. Sample Inp

2019.10.24模拟赛赛后总结

本文原创,如果有不到位的地方欢迎通过右下角的按钮私信我! A.Icow Player 题目描述 被无止境的农活压榨得筋疲力尽后,Farmer John打算用他在MP3播放器市场新买的iCow来听些音乐,放松一下.FJ的iCow里存了N(1 <= N <= 1,000)首曲子,按1..N依次编号.至于曲子播放的顺序,则是按一个Farmer John自己设计的算法来决定: * 第i首曲子有一个初始权值R_i(1 <= R_i <= 10,000). * 当一首曲子播放完毕,接下来播放的

『8.20 模拟赛』旋转的多边形

题目链接戳着里!! 题目描述 解题思路 显然,多边形滚动的时候,指定的点一定是绕着某一个顶点旋转的,旋转的半径就是点到顶点的距离,角度就是顶点所在脚的外角. 如下图所示: 那么我们的问题就转化成了求dis和θ了. dis很简单,只要勾股定理就好了. 那θ呢?也很简单喽,只要链接当前顶点的相邻的两个顶点,运用余弦定理求就好啦,注意一下角度值和弧度制就可以了. (不会余弦定理的小伙伴戳这里==>  Wikipedia & 百度百科) 代码 1 #include<iostream> 2

18.9.20模拟赛T2 城市 枚举

题目大意:给出$N$个数两两的和共$\frac{N \times (N-1)}{2}$个数,请你求出原来的$N$个数输入:第一行一个数$N$,第二行$\frac{N \times (N-1)}{2}$个数表示两两之和(不保证有序)输出:第一行为可行解个数$K$,接下来$K$行每行一个方案,每一个方案的数字从小到大输出,中间有一个空格:方案按字典序从大到小输出.sample input:4 3 6 5 4 5 7 sample output:11 2 3 4数据范围:$2 \leq N \leq

【单调栈维护连续区间】2019.1.18模拟赛T2 浇花

这道题是一道单调栈的题 1 题目描述 2 JDFZ在餐厅门前种了一排nn棵花,每棵花都有一个高度.浇花大爷会枚举所有的区间,然后从区间中找出一个高度最矮的花进行浇水.由于浇花大爷浇完水之后就精疲力竭了,所以请你帮助他计算每棵花都被浇了几次水. 3 4 输入格式 5 第一行一个整数nn. 第二行nn个整数,分别表示每棵花的高度. 6 7 输出格式 8 一行nn个整数用空格隔开,分别表示每棵花被浇了几次水. 9 10 样例一 11 input 12 3 13 1 3 5 14 output 15 3

2019.10.18模拟赛T3

题目大意: 求$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[lcm(i,j)>n](n\leq 10^{10})$的值. 题解: 这题貌似有n多种做法... 为了更好统计,把原式变为$n^2-\sum\limits_{i=1}^n\sum\limits_{j=1}^n[lcm(i,j)\leq n]$. 然后开始毒瘤... 首先,考虑枚举$lcm(i,j)$,设为$d$,计算有多少对$i.j$的最小公倍数为$d$. 设$i=p_1^{a_1}p_2^{a_2}\

2019.10.26模拟赛

T1 序列 给定一长度为\(n\)的序列\(s\),定义其健美值为:\[\sum\limits_{i=1}^{n}|s_i - i|\]因为 zzq 喜欢健美,所以 zzq 希望减小\(s\)的健美值,以衬托 zzq 的健美.为了达到 zzq 的目的,zzq 希望你对序列进行旋转操作,一次旋转操作可以使序列中的所有元素前移一位,并使\(s_1\)移动到\(s_n\). 可以进行任意次旋转操作,zzq 希望旋转后的健美值最小,请找出这个最小值. SOV 智商检测题 我们发现对于每个数,移动每一次会

『8.20 模拟赛』冒泡排序

题目描述 给定n,k,和一个长度为n的序列,请输出这个序列冒泡排序k次之后的结果. 解题思路 我们观察上面给出的伪代码,可以发现这是一段把代码排序成升序的代码,那我们来考虑一下冒牌排序的几个特征. 一个大的数要向右交换,但是一次交换之后就可以换很多位置,所以换一次就不知道跑到哪里去了,所以很难维护. 一个小的数每次最多和它左边的更大的数交换一次,所以一次最多向左边跑一个位置,比大数不知道好维护到那里去了. 进一步思考,k次交换之后,最多可以向左跑k步,也就是说k+1位置的数最远能跑到1的位置上来