zoukankan      html  css  js  c++  java
  • 三进制状压(涂抹果酱)

    题意:https://www.acwing.com/problem/content/1067/

    Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕。

    蛋糕俯视图是一个 N×M 的矩形,它被划分成 N×M 个边长为 1×1×1 的小正方形区域(可以把蛋糕当成 N 行 M 列的矩阵)。

    蛋糕很快做好了,但光秃秃的蛋糕肯定不好看!

    所以,Sam 要在蛋糕的上表面涂抹果酱。

    果酱有三种,分别是红果酱、绿果酱、蓝果酱,三种果酱的编号分别为 1,2,3。

    为了保证蛋糕的视觉效果,Admin 下达了死命令:相邻的区域严禁使用同种果酱。

    但 Sam 在接到这条命令之前,已经涂好了蛋糕第 K 行的果酱,且无法修改。

    现在 Sam 想知道:能令 Admin 满意的涂果酱方案有多少种。请输出方案数 mod106。

    若不存在满足条件的方案,请输出 0。


    三进制状压,因为多了一种状态所以没办法用位运算简便的判断。

    所以我们可以自己写函数。

    #include <bits/stdc++.h>
    typedef long long ll;
    const int mod=1000000;
    using namespace std;
    int n,m,k,stat=1,cnt=1,ban;//stat是总的状态数,ban是第K行的状态 
    int sta[1009],dp[10009][1005];
    bool check(int x){//检验是否有相邻的数 
        int temp=-1;
        for(int i=1;i<=m;i++){
            if(temp==x%3)    return false;//等于上一个数就不行 
            temp=x%3,x/=3;
        }
        return true;
    }
    bool judge(int l,int r){
        for(int i=1;i<=m;i++){
            if(l%3==r%3)    return false;
            l/=3,r/=3;
        }
        return true;
    }
    int main()
    {
        cin>>n>>m>>k;
        stat=ll(pow(3,m));
        for(int i=0;i<stat;i++)
            if(check(i))    sta[cnt++]=i;
        int z;
        for(int i=1;i<=m;i++)//读入第K行的状态
        {
            cin>>z;
            ban=ban*3+z-1; 
        }
        if(!check(ban))    {cout<<0;return 0;}//第K行连在了一起
        int num;//记录第K行对应的下标 
        for(int i=1;i<cnt;i++)    if(ban==sta[i])    num=i;
        for(int i=1;i<=n;i++)
        {
            if(i==k){
                if(i==1)    dp[1][num]=1;
                else{
                    for(int j=1;j<cnt;j++){
                        if(judge(sta[num],sta[j]))
                            dp[i][num]=(dp[i][num]+dp[i-1][j])%mod;
                    }
                }
                continue;    
            }
            for(int j=1;j<cnt;j++)//枚举状态
            {
                if(i==1)    dp[i][j]=1;
                else{
                    for(int k=1;k<cnt;k++)
                    {
                        if(judge(sta[j],sta[k]))//两行的状态不冲突
                            dp[i][j]=(dp[i][j]+dp[i-1][k])%mod; 
                    }
                }
             } 
         }
         ll ans=0;
         for(int i=1;i<cnt;i++)    ans=(ans+dp[n][i])%mod;
         cout<<ans; 
    }
  • 相关阅读:
    windows 上安装redis和windows上redis与php扩展
    mysql存储过程详细讲解及完整实例下载
    html模板生成静态页面及模板分页处理
    php中自动加载类_autoload()和spl_autoload_register()实例详解
    php+mysql事务处理例子详细分析实例
    git学习和常用命令
    block理解
    oc中数组,字典,集合使用的备忘录
    oc log的记录 宏的正确姿势
    swift中的optional
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12505573.html
Copyright © 2011-2022 走看看