题解
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;
}
标签:pre,suf,ll,蓝桥,搭积木,2018,mod,dp,105
From: https://www.cnblogs.com/pure4knowledge/p/18206837