• poj 2411 Mondriaan's Dream 状态压缩dp


     邓姐推荐做这道题,果然是一道不错的题目,据说是插头dp,不过我不会哦,咋办呢,这种题只好暴力乱搞了

    一开始用3进制来存储状态 0代表横放 1代表竖着放朝上 2代表竖着放朝下 然后暴力搜了一下 复杂度3^22 果断超时了

    后来想了一下,其实上一行的每个格子状态都搜完了之后,只要不是朝下 那么就对下一行没有影响了 于是更改了一下状态存储方式

    0代表这个格子放的方式不会影响下一行 1代表会影响下一行

    容易证明 不冲突的两行 下一行有且只有一种合法的方式

    所以复杂度就从 3^22缩减到了2^22  并且二进制存储与位运算 速度飞快 就过了

    具体的就看代码咯

    View Code
    Source Code
    
    Problem: 2411        User: tangrui
    Memory: 416K        Time: 47MS
    Language: C++        Result: Accepted
    Source Code
    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,m;
    long long t[(1<<11)+10][11];
    int x;
    // 0代表仅占自己这行 1代表竖着放占了下一行
    int selfcheck(int a)
    {
        int odd=0;         //相邻的两行同样位置都是0代表这个位置是横着放的 因此必须是偶数个
        for(int k=a,i=0;i<n;i++)
        {
            if(!(k&1))odd=!odd;
            else if(odd) return 0;
            k>>=1;
        }
        if(odd) return 0;
        return 1;
    }
    int correct(int a,int b)
    {
        if(a&b)return 0;          //当相邻的两行有同样位置的两个1时一定是冲突的
        return selfcheck(a|b);  
    }
    long long dp(int now,int k)
    {
    
        if(k==m-1)
        {
            return correct(0,now); //因为最后一行状态只能是0 所以倒数第二行就判断
        }   
        if(t[now][k])return t[now][k]; //你懂的
        for(int i=0;i<x;i++)
        {
            if(correct(i, now))
                t[now][k]+=dp(i,k+1);
        }
        return t[now][k];
    }
    int main()
    {
        while(cin>>n>>m&&(n|m))
        {
            if(n==0||m==0||n*m%2==1)
            {
                cout<<0<<endl;
                continue;
            }
            memset(t,0,sizeof(t));
            if(n>m) swap(n,m);  //为了时间 尽量让n小些
             x=1<<n;            //每一行的总状态数为 2^n
            cout<<dp(0,0)<<endl;
        }
    }
  • 相关阅读:
    server域名与IIS的目录安全性
    机械臂生成URDF文件操作过程
    ROS2 学习参考链接
    solidworks 导入urdf 到ubuntu 在rviz 和 gazebo 显示
    vscode koroFileHeader插件配置
    python 获取当前类中非私有方法
    solidworks 导出urdf 在python ikpy库 使用注意点
    solidworks 打开step 文件并导出文件
    ikpy joint和 link区别
    python 导入包错误
  • 原文地址:https://www.cnblogs.com/goagain/p/2802772.html
Copyright © 2020-2023  润新知