NC222484. USACOOpen20P]Sprinklers2:
描述
输入描述
The first line contains a single integer N.
For each 1≤i≤N, the i+1-st line contains a string of length N denoting the i-th row of the grid. Each character of the string is one of 'W' (indicating a square occupied by a woolly cow), or '.' (unoccupied).
输出描述
Output the remainder when the number of ways to install sprinklers is divided by 109+7.
示例1
输入:
2 .. ..
输出:
28
说明:
Here are all fourteen possibilities when sweet corn can grow at (1,1).示例2
输入:
4 ..W. ..WW WW.. ...W
输出:
2304
说明:
This satisfies the constraints for the first subtask described below.C++ 解法, 执行用时: 171ms, 内存消耗: 67112K, 提交时间: 2021-08-31 13:06:09
#include<bits/stdc++.h> #define mod 1000000007 using namespace std; int n; char s[2005][2005]; int dp[2005][2005][2],pre[2005][2005],suf[2005][2005]; int S[2005],ans; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",s[i]+1),reverse(s[i]+1,s[i]+n+1); for(int i=1;i<=n;i++){ pre[i][0]=1; for(int j=1;j<=n;j++){ pre[i][j]=pre[i][j-1]; if(s[i][j]=='.') pre[i][j]=2*pre[i][j]%mod; } suf[i][n+1]=1; for(int j=n;j>=1;j--){ suf[i][j]=suf[i][j+1]; if(s[i][j]=='.') suf[i][j]=2*suf[i][j]%mod; } } for(int i=0;i<=n;i++){ if(s[1][i+1]=='.'||i==n) dp[1][i][0]=1ll*pre[1][i]*suf[1][min(i+2,n+1)]%mod; if((s[1][i+1]=='.'||i==n)&&(s[1][i]=='.'||i==0)) dp[1][i][1]=1ll*pre[1][max(0,i-1)]*suf[1][min(i+2,n+1)]%mod; } S[n+1]=dp[1][n+1][1]; for(int i=n;i>=1;i--) S[i]=(S[i+1]+dp[1][i][1])%mod; for(int i=2;i<=n;i++){ for(int j=0;j<=n;j++){ (dp[i][j][0]+=1ll*dp[i-1][j][0]*pre[i][n]%mod)%=mod; if(s[i][j+1]=='.'&&j<n) (dp[i][j][0]+=1ll*S[j+1]*pre[i][j]%mod*suf[i][j+2]%mod)%=mod; if(s[i][j]=='.'&&j>0) (dp[i][j][1]+=1ll*dp[i-1][j][0]*pre[i][j-1]%mod*suf[i][j+1]%mod)%=mod; if(s[i][j]=='.'&&s[i][j+1]=='.'&&j<n&&j>0) (dp[i][j][1]+=1ll*S[j+1]*pre[i][j-1]%mod*suf[i][j+2]%mod)%=mod; } S[n+1]=dp[i][n+1][1]; for(int j=n;j>=1;j--) S[j]=(S[j+1]+dp[i][j][1])%mod; } ans=dp[n][0][0]; for(int i=1;i<=n;i++) (ans+=dp[n][i][1])%=mod; printf("%d\n",ans); return 0; }