SRM553 Div1Medium TwoConvexShapes

来源:互联网 发布:乐视自行车软件 编辑:程序博客网 时间:2024/05/22 14:12

【分析】
这道题不要看翻译!看原题!
题目看懂了,然后就蒙逼了。
应该比较容易知道这是一道计数dp。没错,万恶的计数dp!你不仅要知道他有多少种情况,怎样将他简单的实现,而且还要考虑哪些奇奇怪怪的重复情况!
总之,写这道题是崩溃的。直接贴代码。

【代码】

#include <bits/stdc++.h>#define mod 1000000007using namespace std;#define M 55bool to[M][M];char mp[M][M];int dp[M][M];int ans,n,m;void chk(int &x,int y){    x+=y;    if(x>=mod)x%=mod;}struct node{    void down_disrud(){//单调不减         for(int i=0;i<=m;i++)dp[0][i]=1;        for(int i=1;i<=n;i++){            for(int j=0;j<=m;j++){                if(!j)dp[i][j]=0;                else dp[i][j]=dp[i][j-1];                if(to[i][j])chk(dp[i][j],dp[i-1][j]);            }        }        chk(ans,dp[n][m]);    }    void down_disinc(){//单调不增         for(int i=1;i<=n/2;i++){            for(int j=0;j<=m;j++)swap(to[i][j],to[n-i+1][j]);        }        down_disrud();        for(int i=1;i<=n/2;i++){            for(int j=0;j<=m;j++)swap(to[i][j],to[n-i+1][j]);        }    }    void lie_same(){        for(int j=0;j<=n;j++){            bool f=1;            for(int i=1;i<=j&&f;i++){                if(!to[i][m])f=0;            }            for(int i=j+1;i<=n&&f;i++){                if(!to[i][0])f=0;            }            ans-=f;        }    }    void hang_same(){        for(int j=0;j<=m;j++){            bool f=1;            for(int i=1;i<=n;i++)f&=to[i][j];            ans-=f;        }    }    void all_same(){        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                if(mp[i][j]=='W')return;            }        }        chk(ans,1);    }    void solve(){        for(int i=1;i<=n;i++){            for(int j=0;j<=m;j++){                bool &f=to[i][j]=1;                for(int k=1;k<=j&&f;k++){                    if(mp[i][k]=='W')f=0;                }                for(int k=j+1;k<=m&&f;k++){                    if(mp[i][k]=='B')f=0;                }            }        }           down_disrud();        down_disinc();        hang_same();        lie_same();        all_same();    }}T;int main(){    scanf("%d %d",&n,&m);    for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);    T.solve();    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            if(mp[i][j]=='B')mp[i][j]='W';            else if(mp[i][j]=='W')mp[i][j]='B';        }    }    T.solve();    cout<<(ans+mod)%mod<<endl;    return 0;}
0 0