zoukankan      html  css  js  c++  java
  • 【LOJ 10172】涂抹果酱

    题目描述

    Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕。蛋糕俯视图是一个 N×M 的矩形,它被划分成 N×M 个边长为 1×1 的小正方形区域(可以把蛋糕当成 NNN 行 MMM列的矩阵)。蛋糕很快做好了,但光秃秃的蛋糕肯定不好看!所以,Sam 要在蛋糕的上表面涂抹果酱。果酱有三种,分别是红果酱、绿果酱、蓝果酱,三种果酱的编号分别为 1,2,31,2,31,2,3。为了保证蛋糕的视觉效果,Admin 下达了死命令:相邻的区域严禁使用同种果酱。但 Sam 在接到这条命令之前,已经涂好了蛋糕第 KKK 行的果酱,且无法修改。
    现在 Sam 想知道:能令 Admin 满意的涂果酱方案有多少种。请输出方案数 mod106。若不存在满足条件的方案,请输出 000。

    输入格式

    输入共三行。
    第一行:N,MN, MN,M;
    第二行:KKK;
    第三行:MMM 个整数,表示第 KKK 行的方案。
    字母的详细含义见题目描述,其他参见样例。

    输出格式

    输出仅一行,为可行的方案总数。

    样例

    样例输入

    2 2 
    1 
    2 3

    样例输出

    3

    样例说明

    方案一方案二方案三

    2

    1

    2

    数据范围与提示

    对于 30% 的数据,1N×M20;
    对于 60% 的数据,1N1000,1M3;
    对于 100% 的数据,1N10000,1M5。

    题解:三进制的状态压缩类DP,刚拿到题目只能弱弱地DFS扫

               看了题解之后明白啦!!!加了注释昂

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=10003;
    const int mod=1000000;
    int KKK,flag,tnt,n,m,k;
    int f[N][1505],s[1505];
    int cnt,x,ans;
    //f[i][j]表示的是第i行状态为s[j]的方案个数 
    bool check(int x){
        int tmp=0x3f;
        for(int i=1;i<=m;i++){
            if(tmp==x%3) return false;
            tmp=x%3; x/=3;
        }
        return true;
    }
    
    bool judge(int a,int b){
        for(int i=1;i<=m;i++){
            if(a%3 == b%3) return false;
            a/=3; b/=3;
        }
        return true;
    }
    int main(){
        freopen("涂抹果酱.in","r",stdin);
        freopen("涂抹果酱.out","w",stdout);
        cin>>n>>m>>KKK;
        int fire=pow(3,m);
        for(int i=0;i<fire;i++)
            if(check(i)==1) s[++cnt]=i;
        for(int i=1;i<=m;i++){
            cin>>x;
            tnt=tnt*3+x-1;
        }
        for(int i=1;i<=cnt;i++)
            if(tnt==s[i]) { flag=i; break; }
            
        if(!flag) { puts("0"); return 0; }
        for(int i=1;i<=n;i++){
            if(i==KKK){
                if(i==1) f[i][flag]=1;//第一行特殊处理 
                else{
                    for(int j=1;j<=cnt;++j)//枚举上一行状态 
                        if(judge(s[flag],s[j]))
                           f[i][flag]=(f[i][flag]+f[i-1][j])%mod;
                }  
            }
            else{
               for(int j=1;j<=cnt;j++){//枚举上一行的状态 
                    if(i==1) f[i][j]=1; //第一行特殊处理 
                    else{               
                       for(int k=1;k<=cnt;k++)//枚举这一行状态 
                           if(judge(s[j],s[k]))
                              f[i][j]=(f[i][j]+f[i-1][k])%mod;
                    }
                }
            }
        }
        for(int i=1;i<=cnt;i++)
            ans=(ans+f[n][i])%mod;
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    linux下音乐播放软件
    老男孩教育Python自动化开发精英班-开班典礼感想
    【热身】github的使用
    ubuntu12.04下有线网无电缆插入问题
    ubuntu12.04下安装搜狗拼音
    对树莓派学习开发环境的探讨
    Ubuntu12.04下安装VirtualBox
    ubuntu下安装显卡驱动
    ubuntu下使用锐捷校园网
    深度学习之优化算法
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11755214.html
Copyright © 2011-2022 走看看