1. 程式人生 > >【題解】洛谷P1373 小a和uim之大逃離(座標DP)

【題解】洛谷P1373 小a和uim之大逃離(座標DP)

次元傳送門:洛谷P1373

思路

設f[i][j][t][1/0]表示走到(i,j)時 小a減去uim的差值為t 當前是小a取(0) uim取(1)

那麼轉移就很明顯了

f[i][j][t][0]=(f[i][j][t][0]+f[i-1][j][(t-map[i][j]+k)%k][1])%1000000007;//因為當前是小a取 前一步是uim取 差值增加
f[i][j][t][0]=(f[i][j][t][0]+f[i][j-1][(t-map[i][j]+k)%k][1])%1000000007;
f[i][j][t][1]=(f[i][j][t][1]+f[i-1][j][(t+map[i][j]+k)%k][0])%1000000007
;//因為當前是uim取 前一步是小a取 差值減少 f[i][j][t][1]=(f[i][j][t][1]+f[i][j-1][(t+map[i][j]+k)%k][0])%1000000007;

初始化

 f[i][j][map[i][j]%k][0]=1;//因為小a可以從任意一個地方出發

答案存在每個點對應的f陣列中 差值為0 且是uim取值的陣列中

程式碼

#include<iostream>
using namespace std;
int f[805][805][20][2];
int map[805][805];
int n,m,k,ans;
int main()
{
    cin
>>n>>m>>k; k++; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>map[i][j]; f[i][j][map[i][j]%k][0]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int t=0;t<=k;t++) { f[i][j][t][
0]=(f[i][j][t][0]+f[i-1][j][(t-map[i][j]+k)%k][1])%1000000007; f[i][j][t][0]=(f[i][j][t][0]+f[i][j-1][(t-map[i][j]+k)%k][1])%1000000007; f[i][j][t][1]=(f[i][j][t][1]+f[i-1][j][(t+map[i][j]+k)%k][0])%1000000007; f[i][j][t][1]=(f[i][j][t][1]+f[i][j-1][(t+map[i][j]+k)%k][0])%1000000007; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=(ans+f[i][j][0][1])%1000000007; cout<<ans; }