P8675 [蓝桥杯 2018 国 B] 搭积木

原题链接

题解

1.请务必读清题干意思
2.如果以最顶端积木的位置为状态,是可以穷尽所有情况的,则状态为 dp[i][l][r] ,最顶端第 i 层只在区间 [l,r] 内连续放置积木有几种方法
3.状态转移方程 dp[i][l][r]=1lrmdp[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;
}

posted @   纯粹的  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示