• (轮廓线dp)UVA11270-Tiling Dominoes


    (轮廓线dp)UVA11270-Tiling Dominoes:

      题意:

      题解:

        轮廓线dp.对着lrj书上的题解写的.如果将所有格子从左到右,从上到下按顺序排列,则可以dp,f[i][j][k]表示对于第i行第j列的格子前m个格子的状态为k的种类数.

        那么转移有3种情况:

        1.不放,必须保证当前格子上方的那一个格子不为0,否则会有空位.

        2.在当前的格子和当前上方的格子摆一个骨牌.必须保证当前格子上方的那一个格子为0.

        3.在当前的格子和当前左边的格子摆一个骨牌,必须保证当前格子左边的那一个格子为0,且当前格子上方的那一个格子不为0,否则会有空位.

        然后初始化就是把第0个格子的(1<<m)-1设为1,因为你可以假设第0个格子的前m个格子都摆满了骨牌.

        由于n,m小于等于100,则n,m至少有一个小于等于10,把n,m中较小的一个赋给m就行了.

        由于lrj书上的代码用了滚动数组,所以我也用了.

        还有,将i的第j为设为0,用位运算实现就是i&((1<<j)^-1),自己感受一下就知道了吧.

        

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=10;
    int n,m,cur; long long f[2][1<<maxn];
    void clean(int d){
        for(int i=0;i<(1<<m);++i) f[d][i]=0;
    }
    int main(){
        for(;scanf("%d%d",&n,&m)!=EOF;){
            if(n<m) swap(n,m); clean(cur); f[cur][(1<<m)-1]=1;
            for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){
                clean(cur^=1);
                for(int k=0;k<(1<<m);++k){
                    if((k>>(m-1)&1)) f[cur][(k<<1)&((1<<m)^-1)]+=f[cur^1][k];
                    if(i!=1&&!(k>>(m-1)&1)) f[cur][(k<<1)^1]+=f[cur^1][k];
                    if(j!=1&&!(k&1)&&(k>>(m-1)&1)) f[cur][((k<<1)&((1<<m)^-1))^3]+=f[cur^1][k];
                }
            }
            printf("%lld
    ",f[cur][(1<<m)-1]);
        }
        return 0;
    }
  • 相关阅读:
    <c:if></c:if>用法-转载
    Windows下配置Apache服务器
    ScrureCRT访问CentOS时出现乱码的解决办法
    Windows平台下Git服务器搭建
    Group_Concat函数示例
    Mysql Federated Server 示例
    MySQL几个特别语法示例
    MySQL事件调度器
    Disruptor Java版和.NET版的区别
    委托的三种实现方式
  • 原文地址:https://www.cnblogs.com/jxcakak/p/7642457.html
Copyright © 2020-2023  润新知