• LightOJ 1270 Tiles (II)


    题目:http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1270

    题意:给你一个n*m的棋盘 让你用6种砖块填满它,问一共有多少种(砖块不能旋转或翻转)

    写的时候要注意很多细节,不然很容易写错

    因为这里的轮廓线要m+1的长度,所以去下一层的时候必须变换一下状态

    将最高位放到最低位,其他都向前移一位

    之后就是麻烦的分类讨论,具体看代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    typedef unsigned long long ll;
    char a[105][105];
    int now=0,pre=1;
    ll dp[2][1<<12];
    int main()
    {
        int T;
        scanf("%d",&T);
        for(int ca=1;ca<=T;ca++)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            if (n>=m)
            {
                for(int i=0;i<n;i++)
                    scanf("%s",a[i]);
            }
            else
            {
                swap(n,m);
                for(int j=0;j<m;j++)
                    for(int i=n-1;i>=0;i--)
                        scanf(" %c",&a[i][j]);
            }
            int tot=1<<(m+1);
            memset(dp[now],0,sizeof(dp[now]));
            dp[now][tot-1]=1;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    swap(now,pre);
                    memset(dp[now],0,sizeof(dp[now]));
                    for(int st=0;st<tot;st++)
                        if (dp[pre][st])
                    {
                        if (a[i][j]=='.')
                        {
                            if (st&1<<j && !(st&1<<(j+1)))//1
                                dp[now][st|1<<(j+1)]+=dp[pre][st];
                            if (j && j<m-1&& st&1<<j && !(st&1<<(j-1)))//2
                                dp[now][st|1<<(j-1)]+=dp[pre][st];
                            if (j && j==m-1 && st&1<<(j+1) && st&1<<j && !(st&1<<(j-1)))//2
                                dp[now][st|1<<(j-1)]+=dp[pre][st];
                            if (j && j<m-1 && !(st&1<<(j-1)) && !(st&1<<j))//3
                                dp[now][st|1<<(j-1)|1<<j]+=dp[pre][st];
                            if (j && j==m-1 && !(st&1<<(j-1)) && !(st&1<<j) && st&1<<(j+1))//3
                                dp[now][st|1<<(j-1)|1<<j]+=dp[pre][st];
                            if (j<m-1 && st&1<<j && !(st&1<<(j+1)) && !(st&1<<(j+2)))//4
                                dp[now][st|1<<(j+1)|1<<(j+2)]+=dp[pre][st];
                            if (j && st&1<<j && !(st&1<<(j-1)) && !(st&1<<(j+1)))//5
                                dp[now][st|1<<(j-1)|1<<(j+1)]+=dp[pre][st];
                            if (j && !(st&1<<j) && !(st&1<<(j+1)))//6
                                dp[now][st|1<<j|1<<(j+1)]+=dp[pre][st];
                            if (j==m-1)//不放
                            {
                                if (st&1<<j&&st&1<<(j+1))
                                    dp[now][st&~(1<<j)]+=dp[pre][st];
                            }
                            else//不放
                            {
                                if (st&1<<j)
                                    dp[now][st&~(1<<j)]+=dp[pre][st];
                            }
                        }
                        else//不能放
                        {
                            if (j==m-1)
                            {
                                if (st&1<<j&&st&1<<(j+1))
                                    dp[now][st]+=dp[pre][st];
                            }
                            else
                            {
                                if (st&1<<j)
                                dp[now][st]+=dp[pre][st];
                            }
                        }
                    }
                }
                swap(now,pre);
                memset(dp[now],0,sizeof(dp[now]));
                for(int st=0;st<tot;st++)
                    if (dp[pre][st])
                        dp[now][(st<<1|st>>m)%tot]=dp[pre][st];
            }
            printf("Case %d: %llu
    ",ca,dp[now][tot-1]);
        }
        return 0;
    }
    

      

      

  • 相关阅读:
    Git仓库操作笔记[Git repositories]
    supervisor 使用
    python动态加载(二)——动态加载类
    python动态加载(一)——加载方法
    python连接hdfs常用操作
    python对文件进行并行计算初探
    python加载包顺序和PYTHONPATH
    python实现读取数据库的断点续传
    python实现读取文件的断点续传
    python启动一个新进程
  • 原文地址:https://www.cnblogs.com/bk-201/p/7484512.html
Copyright © 2020-2023  润新知