[CF1225Eロックされたプッシュプッシュロック]

タイトル説明

あなたは、今あるM×N個の迷路(すなわちポイント$の左上隅(1,1)$ )、あなたの目標は、右上隅を下げることである(すなわち、迷路到達点(N-、M) )。あなただけ右に一回移動したり、一つのユニットダウンすることができます。例えば、点で(x、y)は次の点に移動することができる(X + 1、Y)または点(X、Y + 1)

いくつかのポイントの岩の迷路、あなたは岩の岩のポイントに移動する(あなたは倉庫番ゲームのボックスにロックを想像することができる)の時点で、あなたのモバイル方向にプッシュし、もしその点になります岩もあり、それはように同じ方向に遠くに押され、されます(たとえば、現在のポイントとして、右が取り付けられて岩の10枚は、あなたがこれらの岩がポイントに右にプッシュされた一点で右歩いているだろう)

迷路は、壁を移動したり、削除されていない石が壁にプッシュするか、壁を破壊することが許可されて囲まれています。(たとえば、あなたが右の石を持って、そして右へ、さらには壁である、あなたは右に移動することはできません)

さて、あなたは多くの異なったプログラムは、最後に達することができるプログラムの数が大きくなる可能性があるため、結果は$のために作る方法を考え出す10 ^ 9 + 7 $の剰余。任意の二つの経路の少なくとも一点異なる場合、これらの2つのプログラムが異なっていることを検討してください。

入力形式

最初の入力ラインは2つの正の整数であるN-、M 、長さと幅、迷路(1≤n、m≤2000)

そこであるn個のラインMの文字が最初の場合は、I 行のJ 番目の文字が「R&LT 」、それはその点を示し(i、j)は、それがある場合にロックが存在することを、「」、これは、その点を示し(Iを、J) I Jは)空です。

データは、出発点を保証する(1,1)は空でなければなりません

出力フォーマット

出力表す整数(1,1)が来る(N、M)プログラムの数の10 ^ 7 + 9 結果モジュロ。

サンプル説明

最初のサンプルは、何の動きは、最後に到達することができなくなりますので、唯一のプログラムパス、出力その1

第二の端部は、端部に到達しない可能性がスキームに到達できない、ブロックされた岩石試料に出力され、0

このURLをクリックして、あなたはhttps://assets.codeforces.com/rounds/1225/index.htmlの図第三のサンプルの例を見ることができます

サンプル入力と出力

入力#1:
  1 1
    。
出力#1:
   1
入力#2:
  2 3
    ...
    ..R
出力#2:
    0
入力#3
  4 4
  ... R
  .RR。
  .RR。
  R ...
出力#3:
  4

-------------------------------------------------- -------------------------------------------------- ------------------------------------

あなたは岩を動かすことができない場合、これはBFSで裸のタイトル。

しかし、元の石の動きの影響が、原因はBFSすることはできません広がります。

 

右または下のみなので、分析を描画することにより、我々は、DAGに(x、y)を知っている方向を

そして、(x、y)をターゲットへの転送がない後にすべての方向の転送経路においては、異なります

ステップ影響、またはアートワーク。

したがって、我々は、BFSを使用することができ、O(Nで(異なる方向にこの点に到達する)まで、現在のポイントまたはM)

転送時間、Oを最適化することができるもののメモリ(N-2 ^(N-Mの+)) 。

 

DPのDPは電流値が周期間隔の値であり、それをサフィックスと最適発見します。

全体的な複雑さはO(NM)。

コードの実装:

#include <iostreamの> 
する#include <cmath> 
の#include <CStringの> 
する#include <cstdioを> 
する#include <CTIME> 
の#include <climits> 
の#include <アルゴリズム>
 の#defineは長い長いllの
 使用 名前空間STDを、
CONSTの INT N = 2010、MOD = 1E9 + 7 INT DP [N] [N] [ 2 ]、合計[N] [N] [ 2 ]、N、M、CNT [N] [N] [ 2 ]。                // 0 1右下
CHAR CH [N] [N]。
int型のmain()
{
    int型I、J、TMP;
    scanf関数(" %d個の%のD "、&​​N、&M)。
    (i = 1 ; iが<= N; iは++)のscanf(" %sの"、CH [I] + 1 )。
    (i = 1 ; iは<; I ++ = N)のための(J = M; J> = 1 ; j--)CNT [I] [J] [ 1 ] = CNT [I]、[J + 1 ] [ 1 ] +(CH [I] [J] == ' ' );
    (J = 1 ; J <= Mであり、j ++)のための(I = N; I> = 1 ; i--)CNT [I] [J] [ 0 ] = CNT [I + 1 ] [j] [ 0 ] +(CH [I] [J] ==" " ); 
     もし(CH [n]は[M] == ' R ')COUT << 0、出口(0 );
    もし(N == 1 && m個の== 1)COUT << 1、出口(0 );
    DP [n]は[M] [ 0 ] DP [n]は[m]を= [ 1 ] = 1 
    和[n]は[M] [ 0 ] =合計[n]が[M] [ 1 ] = 1 以下のための(I = N; I> = 1 ; i-- 
    {
        (J = M; J> = 1 ; j-- 
        {
            もし(I == N && jは== mは)続けます
            TMP = CNT [I + 1 ] [j] [ 0 ]。
            DP [I] [J] [ 0 ] =(SUM [I + 1 ] [j] [ 1 ] -sumを[I + TMP + 1 ] [j] [ 1 ] + MOD)%MOD。
            TMP = CNT [I]、[J + 1 ] [ 1 ]。
            DP [I] [J] [ 1 ] =(SUM [I]、[J + 1 ] [ 0 ] -sum [I] [J + TMP + 1 ] [ 0 ] + MOD)%MOD。
            和[I] [J] [ 0 ] =(SUM [I]、[J + 1 ] [ 0 ] + DP [I] [J] [ 0 ])%MOD。
            和[I] [J] [ 1 ] =(SUM [I + 1 ] [j] [ 1 ] + DP [I] [J] [ 1 ])%MOD。
        }    
    }
    COUT <<(DP [ 1 ] [ 1 ] [ 0 ] + DP [ 1 ] [ 1 ] [ 1 ])%MOD。
    リターン ~~(0 - 0 );
}
 
コードの表示

 

 

 

 

おすすめ

転載: www.cnblogs.com/lhc-yyl-lyx-lyh/p/11762890.html