类似杨辉三角问题——第n杯水

问题:

有一座金字塔,从上到下,第一层有一个杯子、第二层有两个杯子,依次类推。对杯子进行编号,有如下的形状:

   1

 2   3

4   5   6

每个杯子的容量为C升,从塔顶倒下L升水,当1号杯子满了之后,会等量溢出到2号和3号杯子。当2号和3号满了,2号溢出到4号和5号,3号溢出到5号和6号,注意5号接受来自两个杯子的水。依次类推。给定C和L,请问,第n杯里有多少水。

from @陈利人

分析:

此题没有想到好的方法,只想到模拟(或者算DP),

f[leveli, index] 表示第leveli层的第index个酒杯共收到的水的量。那么:

f[leveli, index] = ( f[leveli-1, index-1] – C ) / 2 + ( f[leveli-1, index] – C ) / 2 。

这里 f[leveli-1, index-1]  – C、  f[leveli-1, index] – C 不小于0, 否则相应项为0。

实现:使用hashMap做备忘录,进行DP。

代码:时间复杂度O(n), 空间复杂度O(n)

double getFlow(int C, int leveli, int index, unordered_map<int, double> &hashMap){
	if(index < 0 || index > leveli)
		return 0;
	int n = (leveli + 1) * leveli / 2 + index;//总的索引
	auto p = hashMap.find(n);
	if(p != hashMap.end()) 
		return p->second;
	double leftFlow = getFlow(C, leveli - 1, index -1, hashMap);
	double rightFlow = getFlow(C, leveli - 1, index, hashMap);
	return hashMap[n] = (leftFlow >= C ? (leftFlow - C) / 2 : 0) 
		+ (rightFlow >= C ? (rightFlow - C) / 2 : 0);
}

int main() {
	int L = 10;
	int C = 5; 
	int n = 1;//n值从0开始,表示总的索引
	int leveli = 0, sum = 0;
	while(sum + (leveli + 1) < n + 1) //初始化所在层次:leveli
		sum += leveli++ + 1;
	int index = n - (leveli + 1) * leveli / 2; //计算所在行的索引
	unordered_map<int, double> hashMap;
	hashMap[0] = L;//初始化Map

	double flow = getFlow(C, leveli, index, hashMap);
	cout << (flow > C ? C : flow) << endl;
}

补充:杨辉三角知识

n次的二项式系数对应杨辉三角形的n+1行。
例如:在(a+b)^2=a^2+2ab+b^2中,2次的二项式正好对应杨辉三角形第3行系数1 2 1。

性质:

《类似杨辉三角问题——第n杯水》

《类似杨辉三角问题——第n杯水》

《类似杨辉三角问题——第n杯水》
《类似杨辉三角问题——第n杯水》

    原文作者:杨辉三角问题
    原文地址: https://blog.csdn.net/liql2007/article/details/9639315
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞