2013-07-31 19:55:34Morris

[UVA][dp] 986 - How Many

Universidade da Beira Interior 21-10-2006 

Problem H

How Many?


Let us consider paths in the plane integer lattice Z × Z consisting only of steps (1,1) and (1,−1) and which never pass below the x-axis. A peak at height k is then defined as a point on the path with coordinate y=k that is immediately preceded by a (1,1) step and immediately followed by a (1,−1) step. The pictures below show two such paths: on the left picture we have 4 peaks (2 peaks at height 2 and 2 peaks at height 3); while on the right picture we have 3 peaks (1 peak at height 1, 1 peak at height 2 and 1 peak at height 3).

Problem

The problem consists of counting the number of admissible paths starting at (0,0) and ending at (2n,0) with exactly r peaks at height k.

Input

The input file contains several test cases, each of them consists of one line with the natural numbers n, r and k which define the problem (first number gives n, second number r, and the last one k). Assume that 1 ≤ n < 20, 0 ≤ r < 20, and 1 ≤ k < 20.

Output

For each test case, the output is a single integer on a line by itself, answering the problem, being guaranteed to be less than 231.

Sample Input

3 1 2
10 3 2

Sample Output

2
2002

Maratona Inter-Universitária de Programação 2006 MIUP'2006 


Author: Delfim Torres (Universidade de Aveiro)

題目描述:


找到長度為 2*n 且存在恰好 k 個高度為 r 的山峰,也是有可能會存在比 r 高或低的山峰。

題目解法:


假設一個 dp[i][j][k] 表示當前使用的長度,以及最後停留的位置且已經存在 k 個高度為 R 的山峰。

考慮每一次增加一個隨機高度的山峰,而且增加的時候一定是補上 /\,但於由於要銜接最後停留的高度,
因此會多接幾個 / 來增加高度,直到指定高度。而一定要補上 \,或者多個 \,以確保這個山峰成立。


#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[55][105][55];// len, last height, ? peak at height k
int main() {
    int N, R, K;
    int i, j, k, p, q, r;
    while(scanf("%d %d %d", &N, &R, &K) == 3) {
        memset(dp, 0, sizeof(dp));
        dp[0][0][0] = 1;
        for(i = 0; i <= 2*N; i++) {//len
            for(j = 0; j <= N; j++) {//last height
                for(k = 0; k <= R; k++) {// ? peak at height K
                    if(dp[i][j][k] == 0)
                        continue;
                    for(p = j+1; p <= N; p++) {//next peak
                        int ext = p-j, tk = (p == K);
                        if(tk+k > R)    continue;
                        for(q = p-1; q >= 0; q--) {//last height
                            if(i+ext+p-q > 2*N) break;
                            dp[i+ext+p-q][q][k+tk] += dp[i][j][k];
                        }
                    }
                }
            }
        }
        printf("%d\n", dp[2*N][0][R]);
    }
    return 0;
}