题目:新冠病毒肆虐了好几个月,彻底打乱了大家的学习和生活,终于在阳光明媚的某月,全球迎来了新冠抗战的顺利。为了庆祝全球协力共同抗疫的顺利,同学们准备了一场庆祝晚会,一起幻想以后美好的生活,他们用香槟酒杯搭建了一个小型的金字塔。
金字塔的高度是n,最高层只有一个酒杯,第二层有2个,第三层有3个,以此类推,第n层有n个酒杯。jietmeier同学自荐,担任起往金字塔酒杯倒酒的任务,香槟酒沿着金字塔从最高层依次流到最底层,并逐渐注满每一个酒杯。
已知每秒钟jietmeier向最高层的酒杯倾倒的酒量刚好等于能倒满一个酒杯的酒量,当一个酒杯注满以后,酒就会顺着杯子流下来,并均匀地分向下一层的两个酒杯。如果最底层的酒杯注满了,酒会顺着杯子流到桌子上。为了方便起见,这里不考虑酒在流的过程中停留在杯沿的部分和挥发的部分,并假设酒的流速是足够快的。现在jietmeier想知道,如果他在t秒后停止倒酒,金字塔中会有多少个已经被注满的酒杯?
杨辉三角模拟,dp[i][j]表示当前杯子水量,注意当前水量可以大于一个杯子,因为我们要判断能不能继续向下倒,倒完我们再次讲杯子水量变为1就行了。
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
double dp[20][20];
int t,n;
void fun(){
dp[1][1]+=1.0;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(dp[i][j]>1.0)//说明这个杯子 满了,会溢出
{
dp[i+1][j]+=(dp[i][j]-1.0)/2;
dp[i+1][j+1]+=(dp[i][j]-1.0)/2;
dp[i][j]=1.0;
}
}
}
}
int main(){
cin>>n>>t;
memset(dp,0,sizeof(dp));
while(t--)fun();
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(dp[i][j]>=1.0)ans++;
cout<<ans<<endl;
}