我正在尝试解决UVa Online Judge上的问题Uva-10128 (Queue)。我找不到解决这个问题的方法。我在互联网上搜索,发现大多数人通过使用DP进行预先计算来解决这个问题。
DP[1][1][1] = 1;
for(N = 2; N <= 13; N++)
for(P = 1; P <= N; P++)
for(R = 1; R <= N; R++)
DP[N][P][R] = DP[N-1][P][R]*(N-2) + DP[N-1][P-1][R] + DP[N-1][P][R-1];
以上代码段取自https://github.com/morris821028/UVa/blob/master/volume101/10128%20-%20Queue.cpp。
有人可以解释上面代码中使用的公式。
由于
答案 0 :(得分:1)
当你计算DP[N][P][R]
时,你会看到队列中最小的人的位置。因为他是最小的,他不能阻止任何人。但如果他不站在队列的任何一端,他就会受阻。
如果他是队列中的第一个人,他就会从队伍的开头看到他。因此,如果我们删除了他,则该队列包含N-1
个人,您只能从一开始就看到P-1
个人,但最后仍会R
个人。因此,有DP[N-1][P-1][R]
种组合。
如果他在中间,那么通过删除他我们仍然可以看到P
和R
人。由于中间有N-2
个位置,因此有DP[N-1][P][R] * (N-2)
个组合。
如果他是队列中的最后一个人,我们会得到DP[N-1][P][R-1]
个组合。推理与第一种情况完全相同。
因此DP[N][P][R]
的组合总数是所有三种情况的总和。