CF1225E Rock Is Push 題解
阿新 • • 發佈:2022-05-28
一般這種 dp 的轉移都是相鄰格子之間的,但是這道題相鄰格子之間轉移沒辦法搞掉題目的這個限制。考慮每次轉向的時候轉移,這樣對於某一個點,他能轉移的一定是一個區間(不能到最後 \(cnt\) 個,那樣就把石頭推出去了)。暴力做是 \(O(n^3)\) 的,區間的這個可以字首和優化,就 \(O(n^2)\) 了。
點選檢視程式碼
const int N=2000+13; int n,m; char s[N][N]; ll f[N][N][2],g[N][N][2],sum[N][N][2]; int main(){ read(n),read(m); for(int i=1;i<=n;++i) read(s[i]+1); if(n==1&&m==1) return print(1),0; //0-Right 1-Down for(int i=n;i;--i) for(int j=m;j;--j){ sum[i][j][0]=sum[i][j+1][0]+(s[i][j]=='R'); sum[i][j][1]=sum[i+1][j][1]+(s[i][j]=='R'); } f[n][m][0]=f[n][m][1]=g[n][m][0]=g[n][m][1]=1; for(int i=n;i;--i) for(int j=m;j;--j){ if(i==n&&j==m) continue; f[i][j][0]=(g[i][j+1][1]-g[i][m-sum[i][j+1][0]+1][1]+mod)%mod,f[i][j][1]=(g[i+1][j][0]-g[n-sum[i+1][j][1]+1][j][0]+mod)%mod; g[i][j][0]=(g[i+1][j][0]+f[i][j][0])%mod,g[i][j][1]=(g[i][j+1][1]+f[i][j][1])%mod; } println((f[1][1][0]+f[1][1][1])%mod); return 0; }