CF1225E explanations Rock Is Push

CF playing when I did not expect this www dp really quite clever

This is a question dp (nonsense

Suppose we went to the \ ((i, j) \ ) position, because we can only move down / right, then all we are left with the top of the rock (that is, \ (\ {(i, j ) | i <n \ space || \ space j <m \} \) stones) no matter there are pushed to and I have no melon (can draw a few pictures a little push, it is quite obvious), that is, the problem no after-effect available dp solved.

Together count is not very good, we can consider them separately to the right and down dp.

So we can use the array \ (rs, ds \) to record the number of stones and rocks below the number to the right of a position, because only these stones to \ ((i, j) \ ) state of metastasis

Provided a two-dimensional array state \ (R & lt, D \) , represents the \ ((i, j) \ ) position next to the right ( \ (R & lt \) ) or down ( \ (D \) ) to go to reach the target position \ ((n, m) \ ) the total number of programs available from the defined \ (R & lt [n-] [m] = D [n-] [m] =. 1 \) .

Key to mess w: state transition equation

The reason why this question ingenious, first, because it is divided into \ (r, d \) two to dp, then one is a state transition equation.

Capture .PNG

As shown above, we assumed the grid in yellow \ ((I, J) \) , blue circle of stone, stone dotted line trajectories. Then easy to get \ (DS [I] [J] =. 1 \) ( \ (RS \) defines forget see above). The next step because we have to go down, so we can choose continuous walking \ (1 \) step, \ (2 \) steps ... until \ (ni-ds [i] [j] \) until the step, At this time, just below the stones are all pushed one by one into the wall lined. Thus i.e., state transition equation

\[d[i][j]=\sum_{k=1}^{n-i-ds[i][j]}r[i][j+k]\]

\[r[i][j]=\sum_{k=1}^{m-i-rs[i][j]}d[i+k][j]\]

(Solution ahead of a doubt: here for \ (r \) array sum rather than \ (d \) reason array summation is that we continuously go down \ (k \) after the next step should be to the right, so used here \ (R & lt \) , and vice versa)

Think still quite coincidentally (or is it too weak nest qaq

Of course, a enum \ (r [i] [j + k], d [i + k] [j] \) will certainly be a timeout, so here we use the prefix and save.

If you still did not understand the point of dalao can look konjac code comments www ~

code:

#include<bits/stdc++.h>
using namespace std;
long long n , m , r[2100][2100] , d[2100][2100] , ds[2100][2100] , rs[2100][2100];
long long sumr[2100][2100] , sumd[2100][2100];
const int mod = 1e9 + 7;
char s[2100];
//d:down r:right
int main()
{
    scanf("%d%d" , &n , &m);
    for(register int i = 1 ; i <= n ; i++ )
    {
        scanf("%s" , s + 1);
        for(register int j = 1 ; j <= m ; j++ )
        {
            if(s[j] == 'R') rs[i][j] = 1 , ds[i][j] = 1;
        }
    }
    if(n == 1 && m == 1)
    {
        cout << (rs[1][1] ^ 1);
        return 0;
    }
    for(register int i = n ; i >= 1 ; i-- )
    {
        for(register int j = m ; j >= 1 ; j-- )
        {
            ds[i][j] += ds[i][j + 1];
            rs[i][j] += rs[i + 1][j];
        }
    }
    r[n][m] = d[n][m] = sumd[n][m] = sumr[n][m] = 1;
    for(register int i = n ; i >= 1 ; i-- )
    {
        for(register int j = m ; j >= 1 ; j-- )
        {
            if(i == n && j == m) continue;
            r[i][j] = (sumd[i][j + 1] - sumd[i][m - ds[i][j + 1] + 1]) % mod;
            d[i][j] = (sumr[i + 1][j] - sumr[n - rs[i + 1][j] + 1][j]) % mod;
            //+1 : sum±Ø±¸  n - ds : ¼´i + (n - i - ds)»¯¼òºóµÄ½á¹û.
            //d[i][j] : ´Ë²½ÏòÏÂ×ߺóÓм¸ÖÖ¿ÉÄܵ½(n , m); r[i][j] : ÏòÓÒ×ß
            //ds[i][j] : (i , j) ÏÂÃæÓжàÉÙ¿éʯͷ , rs[i][j] : (i , j)ÓÒ±ß 
            //d[i][j] = sum(r[n - i - 1...ds[i][j + 1] + i][j]) , rͬÀí
            //ÒâΪÔÚÏÂÒ»¸öÏòÓÒ×ß֮ǰ£¬Ñ¡ÔñÏòÏÂ×ß1...ds[i][j + 1]´Î£¬È»ºóÔÙÏòÏÂ×ߵķ½°¸ÊýÖ®ºÍ¡£
            //ÇÉÃîwww
            sumr[i][j] = (sumr[i + 1][j] + r[i][j]) % mod; 
            sumd[i][j] = (sumd[i][j + 1] + d[i][j]) % mod; 
        }
    }
    /*for(register int i = 1 ; i <= n ; i++ )
    {
        for(register int j = 1 ; j <= m ; j++ )
        {
            cout << d[i][j] << ' ';
        }
        cout << endl;
    }
    cout << endl;
    for(register int i = 1 ; i <= n ; i++ )
    {
        for(register int j = 1 ; j <= m ; j++ )
        {
            cout << r[i][j] << ' ';
        }
        cout << endl;
    }*/
//  cerr << r[1][1] << " " << d[1][1] << endl;
    cout << ((r[1][1] + d[1][1]) % mod + mod) % mod;
    return 0;
}

Guess you like

Origin www.cnblogs.com/lost-in-tianyi/p/11762166.html