• 刷题记录:牛客NC16856[NOI1999]钉子和小球


    传送门:牛客

    [NOI1999] 钉子和小球

    题目描述

    有一个三角形木板,竖直立放,上面钉着 $ \frac{ n (n+1) } { 2 } $ 颗钉子,还有 ( n + 1 n+1 n+1) 个格子 (当 n = 5 n=5 n=5 时如图 1 ) 。每颗钉子和周围的钉子的距离都等于 d d d ,每个格子的宽度也都等于 d d d ,且除了最左端和最右端的格子外每个格子都正对着最下面一排钉子的间隙。
    让一个直径略小于 d d d 的小球中心正对着最上面的钉子在板上自由滚落,小球每碰到一个钉子都可能落向左边或右边 (概率各 1 / 2 1/2 1/2 ) ,且球的中心还会正对着下一颗将要碰上的钉子。例如图2 就是小球一条可能的路径。

    我们知道小球落在第 i i i 个格子中的概率 p i p_i pi = $ \frac{C_n^i }{ 2^n} $ = $ \frac{ n! }{ 2^n i! (n-i)! } $ ,其中 i i i 为格子的编号,从左至右依次为 $ 0 , 1 , … , n $.
    现在的问题是计算拔掉某些钉子后,小球落在编号为 m m m 的格子中的概率 p m p_m pm 。假定最下面一排钉子不会被拔掉。例如图3 是某些钉子被拔掉后小球一条可能的路径。

    输入:
    5 2
        *    
       * .
      * * *
     * . * *
    * * * * *
    输出:
    7/16
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    emmm,感觉这是一道比较容易的区间dp的题目吧(虽然洛谷上评级为蓝)

    主要思路:

    1. 首先我们会发现题目上说的是每一次碰到我们的钉子都各自有1/2的概率走向两边,最后的是求出最后位置的概率,但是分数的累加问题比较麻烦.所以我们可以将分数转化为整数来运算(emmm,就是将刚开始的1分成为2^n),也就是说我们可以认为刚开始掉落的不是一个小球而是 2^n,这样的话我们每一次分成两半就除二就行了,这样也能保证都是整数

    注意我们求2^n时不能使用 << 运算符,因为是long long 的原因,可能运算符会爆掉??我当时换了快速幂就过了

    1. 搞完我们的预处理之后,我们就可以构思我们的dp方程了.我们可以使用

    dp[i+1][j]=dp[i+1][j]+dp[i][j]/2          a[i][j]=‘*’

    dp[i+1][j+1]=dp[i+1][j+1]+dp[i][j]/2          a[i][j]=‘*’

    dp[i+2][i+1]=dp[i+2][i+1]+dp[i][j]          a[i][j]!=‘*’

    上面的dp方程就是模拟下落过程,假设有钉子,就分成两部分继续下落,反之落到下面的两格的位置即可

    对于最终的答案,我们可以将格子变成一个个钉子即可.在dp中补上一行即可

    ll yinzi=gcd(dp[n+1][m+1],dp[1][1]);
    printf("%lld/%lld\n",dp[n+1][m+1]/yinzi,dp[1][1]/yinzi);
    
    • 1
    • 2

    因为最终是求既约分数的,所以我们还需要求出gcd

    下面是具体的代码部分:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    using namespace std;
    typedef long long ll;
    #define inf 0x3f3f3f3f
    #define root 1,n,1
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    inline ll read() {
    	ll x=0,w=1;char ch=getchar();
    	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    	return x*w;
    }
    #define maxn 1000000
    #define ll_maxn 0x3f3f3f3f3f3f3f3f
    const double eps=1e-8;
    ll n,m;
    unsigned long long dp[100][100];
    char a[100][100];
    ll gcd(ll a,ll b) {
    	if(b==0) return a;
    	else return gcd(b,a%b);
    }
    ll qpow(ll a, ll b){
    	ll res = 1;
    	while(b){
    		if(b & 1)	res *= a;
    		a *= a;
    		b >>= 1; 
    	}
    	return res;
    }
    int main() {
    	n=read();m=read();
    	for(int i=1;i<=n;i++) {
    		for(int j=1;j<=i;j++) {
    			cin>>a[i][j];
    		}
    	}
    	dp[1][1]=qpow(2,n+1);
    	for(int i=1;i<=n;i++) {
    		for(int j=1;j<=i;j++) {
    			if(a[i][j]=='*') {
    				dp[i+1][j]+=dp[i][j]/2;
    				dp[i+1][j+1]+=dp[i][j]/2;
    			}else {
    				dp[i+2][j+1]+=dp[i][j];
    			}
    		}
    	}
    	ll yinzi=gcd(dp[n+1][m+1],dp[1][1]);
    	printf("%lld/%lld\n",dp[n+1][m+1]/yinzi,dp[1][1]/yinzi);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
  • 相关阅读:
    高新技术企业认定标准是什么?
    IBM HTTP Server ( IHS服务器)SSL证书安装教程
    BT - Unet:生物医学图像分割的自监督学习框架
    王道 第一章 计算机网络的概念
    网页视频下载工具 iTubeGo mac中文版软件特色
    RT-DETR优化改进:IoU系列篇 | Inner-IoU融合MPDIoU,创新十足,2023年11月最新IoU改进
    第六节量变质变规律、否定之否定规律
    如何修改域名DNS服务器?修改DNS服务器常见问题汇总
    CH9101国产USB转异步串口芯片兼容替代PL2303GC/PL2303HXD/FT230X/FT232RQ/CY7C65213
    SpringBoot开启异步多线程
  • 原文地址:https://blog.csdn.net/yingjiayu12/article/details/127587424