1. 程式人生 > 實用技巧 >J:Grid Coloring(dp)

J:Grid Coloring(dp)

題意:給定一個n*m的網格,每個格子可能被塗了藍色或者紅色,也有可能空白,規定藍色的左上部分全部都只能為藍,問有多少種塗法。

思路:dp,dp[i][j]表示第i行的前j個全部為Blue的方案數,l[i]表示第i行能把前一部分塗藍的左邊界,r[i]為右邊界,從下層往上層遞迴,dp[i][j]+=dp[i+1][k];

程式碼:

#include<bits/stdc++.h>
using namespace std;
char g[35][35];
int l[33],r[33];
long long dp[33][33];
int n,m;
long long ans;
int main()
{
    scanf("%d%d",&n,&m);
    int f=1;
    for(int i=1;i<=n;i++)
    {
        cin>>g[i]+1;
        l[i]=0;r[i]=m;
        for(int j=1;j<=m;j++)
        {
            if(g[i][j]=='B')l[i]=max(l[i],j);
            if(g[i][j]=='R')r[i]=min(r[i],j-1);
        }
        if(l[i]>r[i])f=0;
    }
    if(!f)printf("0\n");
    else
    {
        for(int i=l[n];i<=r[n];i++)dp[n][i]=1;
        for(int i=n-1;i>=1;i--)
        {
            for(int j=l[i];j<=r[i];j++)
            {
                for(int k=l[i+1];k<=r[i+1]&&k<=j;k++)
                dp[i][j]+=dp[i+1][k];
            }
        }
        for(int i=l[1];i<=r[1];i++)ans+=dp[1][i];
        printf("%lld\n",ans);
    }
    return 0; 
}