• 三进制状压(涂抹果酱)


    题意: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; 
    }
  • 相关阅读:
    Asp.net MVC routing 路由
    Asp.net MVC3 企业网站系统高仿博客园 首页左侧列表页面 实现效果
    Asp.net MVC 3 开发简单的企业系统开篇数据库
    Asp.net MVC 3 开发企业网站系统仿照博客园部分功能总体设计
    [转]C语言中的文件格式化读写函数:fprintf和fscanf
    如何讀取/寫入文字檔? (IC Design) (Verilog)
    Verilog状态机的编写学习
    [转] verilog中的integer和reg的差别
    verilog常用系统函数以及例子
    独立写testbench注意的几点
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12505573.html
Copyright © 2020-2023  润新知