Large Luo Gu P1373 and a small sum to flee uim

Original title link

Topic background

Uim came to a small and rainforest adventure. Suddenly a burst of north wind blowing, a dark cloud from over the northern horizon streamed in, it was accompanied by a lightning, waves of thunder. Suddenly, blustery, dark clouds covered the sky, followed by beans big rain knocked down from the sky, I saw the front there is a disheveled, buck-toothed monster, the deep voice said: "Oh, since you came to this , can only survive a!. " A small and his little friends are shocked!

Title Description

Moment, there is a huge matrix of n * m on the ground, there is a lump of 0 ~ k unequal amounts of the devil on each grid matrix. Each gave a little monster and uim a magic bottle and said, you can start from either a matrix grid, each right or go down one step, from either end of a grid. Beginning with a small magic Bottle absorbent liquid on the ground, the next step is absorbed by the UIM, so alternately continue, and the final step required to be absorbed by uim. Bottle capacity only k, that is, if k + 1 then installed Bottle will be cleared to zero, if k + 2 installed on the left one, and so on. Monster also said, who finally bottled the magic of magic liquid and more, who will be able to survive. Uim a small and deep feelings, like brothers, how can I bear to let small partners away from their own it? Silent for a moment, a little inspiration, if They magic bottle as much as the devil, not to be able to survive it? A little small and his partners have spent laughing!

Now he wants to know how many ways they can survive there.

Input and output formats

Input formats:

 

The first row, three spaces separated integers n, m, k

Subsequently n rows, m columns, each matrix representing a liquid amount of magic. The numbers on the same line separated by a space.

 

Output formats:

 

An integer representing the number of ways. Due to be large, the output result of taking more than 1 000 000 007.

 

Sample input and output

Input Sample # 1:  Copy
2 2 3
1 1
1 1
Output Sample # 1:  Copy
4

Explanation

Sample [explain]

Sample Explanation: four options are: (1,1) -> (1,2), (1,1) -> (2,1), (1,2) -> (2,2), (2 , 1) -> (2,2).

【data range】

For 20% of the data, n, m <= 10, k <= 2

For 50% of the data, n, m <= 100, k <= 5

To 100% of the data, n, m <= 800,1 <= k <= 15

 

answer

This problem will soon be able to see the face of dynamic programming thought, it is not difficult to come up with a five-dimensional dp approach:

Design $ f_ {i, j, k, l, p} $ represents the number of programs

$ I, j $ represents the current position $ (i, j) $ ($ i, j \ in [1,800] $)

$ K, l $, respectively, and a small amount of magic night of uim ($ k, l \ in [0,15] $ $ 15 $ note here comprises, as the actual modulus is $ k + 1 $)

$ P $ represent the current round, $ p = 0 $ then turn a small walk, $ p = 1 $ then turn away uim

The final answer is $ \ Sigma_ {i = 1} ^ {n} {\ Sigma_ {j = 1} ^ {m} {\ Sigma_ {l = 0} ^ {k-1} {f_ {i, j, l, l, 1}}}} $

But it is clear that this state will burst design space must be reduced one-dimensional. Observe the above formula, you will find the answer in two l seem inexplicable. Because we only care about two magic are equal , they do not care about their specific values . Therefore, we will turn into a two-dimensional state $ k = kl $. Obviously, this does not indicate the exact state after experiencing modulus, because the amount of information has decreased, but the $ k \ $ when neq0, two magic certainly not equal, this would certainly equal, and after each overlay difference is still correct , so this method necessarily effective.

State may be designed so that:

Design $ f_ {i, j, k, l, p} $ represents the number of programs

$ I, j $ represents the current position $ (i, j) $ ($ i, j \ in [1,800] $)

$ K $ represents the difference magic night and a small amount of uim ($ k \ in [0,15] $ $ 15 $ note here comprises, as the actual modulus is $ k + 1 $)

$ P $ represent the current round, $ p = 0 $ then turn a small walk, $ p = 1 $ then turn away uim

The final answer is $ \ Sigma_ {i = 1} ^ {n} {\ Sigma_ {j = 1} ^ {m} {f_ {i, j, 0,1}}} $

Initialization

for(int i=1;i<=N;i++)
    for(int j=1;j<=M;j++){
        scanf("%d",a[i]+j);
        f[i][j][modk(a[i][j])][0]=1;
    }

 

There are state transition equation

for(int i=1;i<=N;i++)
    for(int j=1;j<=M;j++){
        for(int k=0;k<K;k++){
            /*0:a 1:uim  k->a*/
            if(i>1){/*from above*/
                add(f[i][j][k][0],f[i-1][j][modk(k-a[i][j])][1]);
                add(f[i][j][k][1],f[i-1][j][modk(k+a[i][j])][0]);
            }
            if(j>1){/*from backward*/
                add(f[i][j][k][0],f[i][j-1][modk(k-a[i][j])][1]);
                add(f[i][j][k][1],f[i][j-1][modk(k+a[i][j])][0]);
            }
        }
        add(ans,f[i][j][0][1]);
    }

 

The final program is very simple

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MOD=1e9+7,MAXN=805,MAXK=16;
 4 int N,M,K,a[MAXN][MAXN];
 5 int f[MAXN][MAXN][MAXK][2],ans;
 6 inline int modk(int x){/*MOD into 0~k-1*/
 7     return (x+K)%K;
 8 }
 9 inline void add(int &x,int y){
10     x=(x+y)%MOD;
11 }
12 int main(){
13 //    freopen("1.in","r",stdin);
14 //    freopen("2.out","w",stdout);
15     scanf("%d%d%d",&N,&M,&K);
16     K++;
17     for(int i=1;i<=N;i++)
18         for(int j=1;j<=M;j++){
19             scanf("%d",a[i]+j);
20             f[i][j][modk(a[i][j])][0]=1;
21         }
22 
23     for(int i=1;i<=N;i++)
24         for(int j=1;j<=M;j++){
25             for(int k=0;k<K;k++){
26                 /*0:a 1:uim  k->a*/
27                 if(i>1){/*from above*/
28                     add(f[i][j][k][0],f[i-1][j][modk(k-a[i][j])][1]);
29                     add(f[i][j][k][1],f[i-1][j][modk(k+a[i][j])][0]);
30                 }
31                 if(j>1){/*from backward*/
32                     add(f[i][j][k][0],f[i][j-1][modk(k-a[i][j])][1]);
33                     add(f[i][j][k][1],f[i][j-1][modk(k+a[i][j])][0]);
34                 }
35             }
36             add(ans,f[i][j][0][1]);
37         }
38 
39     printf("%d",ans);
40     return 0;
41 }
View Code

 

Guess you like

Origin www.cnblogs.com/guoshaoyang/p/11114213.html