原題連結
題解
1.請務必讀清題幹意思
2.如果以最頂端積木的位置為狀態,是可以窮盡所有情況的,則狀態為 \(dp[i][l][r]\) ,最頂端第 \(i\) 層只在區間 \([l,r]\) 內連續放置積木有幾種方法
3.狀態轉移方程 $dp[i][l][r]=\sum_1^l \sum_r^m dp[i+1][x][y] $
把 \(x,y\) 看成二維座標上的點,則上圖的sum可以用二維差分的方式求出
code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll pre[105][105]={0};
int suf[105][105]={0};
ll dp[105][105][105]={0};
const ll mod=1e9+7;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll n,m;
cin>>n>>m;
for(ll i=1;i<=n;i++)
{
string s;
cin>>s;
for(ll j=1;j<=m;j++)
{
pre[i][j]=pre[i][j-1]+(s[j-1]=='X');
}
}
for(ll i=n;i>=1;i--)
{
for(ll l=1;l<=m;l++)
{
for(ll r=m;r>=l;r--)
{
if(pre[i][r]-pre[i][l-1]!=0) continue;
if(i==n) dp[i][l][r]=1;
else dp[i][l][r]=suf[l][r];
dp[i][l][r]%=mod;
}
}
for(int l=1;l<=m;l++)
{
for(int r=m;r>=1;r--)
{
suf[l][r]=((suf[l-1][r]+suf[l][r+1])%mod-suf[l-1][r+1])%mod+dp[i][l][r];
suf[l][r]%=mod;
}
}
}
ll ans=1;
for(ll i=1;i<=n;i++)
{
for(ll l=1;l<=m;l++)
{
for(ll r=l;r<=m;r++)
{
ans+=dp[i][l][r];
//printf("(%d,%d,%d) %d\n",i,l,r,dp[i][l][r]);
ans%=mod;
}
}
}
cout<<ans;
return 0;
}