interviewstreet - Grid Walking 动态规划

来源:互联网 发布:网页游戏数据修改器 编辑:程序博客网 时间:2024/06/07 06:39

题目来源:https://www.interviewstreet.com/challenges/dashboard/#problem/4e48bfab1bc3e

解题报告:

首先计算组合值C[m][n],按照公式C[m][n] = C[m-1][n-1] + C[m-1][n]获得。

f[i][j][k],代表第i维,位于位置j时,走k步有几种走法。

则有方程f[i][j][k] = f[i][j-1][k-1] + f[i][j+1][k-1],考虑j-1<=0, j+1>D[i]的情况

path[i]k],代表只变化第0维到第i维,走k步,有几种走法。

则有path[0][k] = f[0][X[0]][k], 1<= k <= M

且path[i][k] = SUM ( C[k][j] * path[i-1][j] * f[i][X[i]][k-j] ) , 对每个j, 0<= j <= k

最后输出path[N-1][M]。

这题的关键在于大数据!!!,所以用long long,然后在每个地方加 % 1000000007,我因为漏在几个地方加这个,WA了快20次了吧T_T

#include <iostream>using namespace std;long long f[10][100][301];long long path[10][301];int C[301][301];int main(){    int T;    cin >> T;    C[0][0] = 1;    for (int i = 1; i <= 300; i++)    {        C[i][0] = 1;        C[i][i] = 1;        for (int j = 1; j < i; j++)            C[i][j] = (C[i-1][j-1] + C[i-1][j]) % 1000000007;    }    while(T-- > 0)    {        int N;        int M;        cin >> N >> M;        int *X = new int[N];        int *D = new int[N];                for (int i = 0; i < N; i++)        {            cin >> X[i];            X[i]--;        }        for (int i = 0; i < N; i++)        {            cin >> D[i];        }        for (int i = 0; i < N; i++)        {            for (int k = 0; k <= M; k++)            {                path[i][k] = 0;                for (int j = 0; j < D[i]; j++)                    f[i][j][k]=0;            }        }                for (int i = 0; i < N; i++)        {            path[i][0] = 1;            for (int j = 0; j < D[i]; j++)                f[i][j][0] = 1;        }                for (int i = 0; i < N; i++)        {            for (int k = 1; k <= M; k++)            {                for (int j = 0; j < D[i]; j++)                {                    if (j - 1 >= 0)                    {                        f[i][j][k] += f[i][j-1][k-1] % 1000000007;                        f[i][j][k] = f[i][j][k] % 1000000007;                    }                    if (j + 1 < D[i])                    {                        f[i][j][k] += f[i][j+1][k-1] % 1000000007;                        f[i][j][k] = f[i][j][k] % 1000000007;                    }                    f[i][j][k] = f[i][j][k] % 1000000007;                }            }                                }        for (int k = 1; k <= M; k++)            path[0][k] = f[0][X[0]][k];                for (int i = 1; i < N; i++)        {            for (int k = 1; k <= M; k++)            {                path[i][k] = 0;                for (int j = 0; j <= k; j++)                {                    path[i][k] += ((C[k][j] * (path[i-1][j] % 1000000007)) % 1000000007)  * (f[i][X[i]][k-j] % 1000000007) % 1000000007;                    path[i][k] = path[i][k] % 1000000007;                }            }        }        cout << path[N-1][M] % 1000000007 << endl;        delete[] X;        delete[] D;    }}


附录:

Grid Walking (Score 50 points) 
You are situated in an N dimensional grid at position(x_1,x2,...,x_N). The dimensions of the grid are (D_1,D_2,...D_N). In one step, you can walk one step ahead or behind in any one of the N dimensions. (So there are always 2N possible different moves). In how many ways can you take M steps such that you do not leave the grid at any point ? You leave the grid if you for any x_i, either x_i <= 0 or x_i > D_i.

Input:
The first line contains the number of test cases T. T test cases follow. For each test case, the first line contains N and M, the second line contains x_1,x_2...,x_N and the 3rd line contains D_1,D_2,...,D_N.

Output:
Output T lines, one corresponding to each test case. Since the answer can be really huge, output it modulo 1000000007.

Constraints: 1 <= T <= 10
1 <= N <= 10
1 <= M <= 300
1 <= D_i <= 100
1 <= x_i <= D_i

Sample Input #00:
10
1 287
44
78
1 236
25
87
1 122
41
63
1 260
7
64
1 127
3
73
1 69
6
68
1 231
14
63
1 236
13
30
1 259
38
70
1 257
11
12
Sample output: 
38753340
587915072
644474045
423479916
320130104
792930663
846814121
385120933
60306396
306773532