zoukankan      html  css  js  c++  java
  • Gym

    题目传送门

    题目大意:

    给出n*m的网格,有红蓝两种颜色,每个格子都必须被染色,当一个格子被染成蓝色后,这个格子左上方的一块都必须被染成蓝色,问最后的方案数量。

    思路:

    按照题目条件,如果有一个格子被染成了红色,则这个格子的右下方要全部被染成红色,也就是这个给出的网格能让我们染色的,是一个左上方和右下方都是阶梯型的图形,而对于每一行来说,当一个格子被染成了蓝色,那么左边的所有格子都必须被染成蓝色,所以我们设 f[ i ][ j ] 表示第 i 行 第 j 个格子被染成蓝色的方案数量,那么这个dp方程就是 f[ i ][ j ] += f[ i+1 ][ k ](0<=k<=m)。

    而对于每一行,我们可以预处理出这一行的能填蓝色的左右边界,最下面一行能填颜色的赋值为1(注意,f [ n ][ 0 ]也要赋值,这表示这一行全填为红色)。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<string.h>
    #include<sstream>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<bitset>
    #include<unordered_map>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    inline int rd() {
        int f = 1;
        int x = 0;
        char s = getchar();
        while (s<'0' || s>'9') {if (s == '-')f = -1;s = getchar();}
        while (s >= '0'&&s <= '9') {x = x * 10 + s - '0';s = getchar();}
        x *= f;return x;}
    inline ll gcd(ll a, ll b) {
        if (b == 0)return a;
        return gcd(b, a%b);
    }
    int n,m;
    char mp[40][40];
    int l[40],r[40];
    ll f[40][40];
    int flag=0;
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++) {
            scanf("%s",mp[i]+1);
            l[i]=0,r[i]=m;
            for(int j=1; j<=m; j++) 
            {
                if(mp[i][j]=='B')  l[i]=max(l[i], j );
                if(mp[i][j]=='R')  r[i]=min(r[i], j - 1);
            }
    
            if(r[i]<l[i])flag=1;
        }
        if(flag) {
            printf("0
    ");
            return 0;
        }
        for(int i=l[n]; i<=r[n]; i++) 
        {
            f[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++) 
                {
                    f[i][j]+=f[i+1][k];
                }
            }
        }
        ll sum=0;
        for(int i=0; i<=m; i++)sum+=f[1][i];
        printf("%lld
    ",sum);
    
    }
    View Code
  • 相关阅读:
    策略模式浅谈
    J.U.C 系列之 Tools
    RCP 主题切换
    C#利用WebClient 两种方式下载文件
    淘宝联盟
    微信公众账号开发练习1成为开发者
    第一次使用mssql游标
    C#利用com操作excel释放进程
    免费空间主机屋试用体验
    Ajax简单聊天B/S
  • 原文地址:https://www.cnblogs.com/mountaink/p/9550936.html
Copyright © 2011-2022 走看看