题目描述

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 3 
1 2
2 3 
3 1
2 3 
3 2

数据范围与提示

对于 30% 的数据,1≤N×M≤20;
对于 60% 的数据,1≤N≤1000,1≤M≤3;
对于 100% 的数据,1≤N≤10000,1≤M≤5。

 
这道题用状压DP,是三维的,有很多细节要注意处理。
其中我用了比较笨的储存方法,但是能有效地忽略掉特殊行。
具体看代码,不懂评论。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define MAXN 100010
#define INF 10000009
#define MOD 1000000
#define LL long long
#define in(a) a=read()
#define REP(i,k,n) for(int i=k;i<=n;i++)
#define DREP(i,k,n) for(int i=k;i>=n;i--)
#define cl(a) memset(a,0,sizeof(a))
inline int read(){
int x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
inline void out(int x){
if(x<) putchar('-'),x=-x;
if(x>) out(x/);
putchar(x%+'');
}
int n,m,k;
int pow[];
LL f[][];
struct node{
LL num,a[];
}tree[];
bool check1(int a,int b){
int sa[],sb[],na=m+,nb=m+;
memset(sa,,sizeof(sa));
memset(sb,,sizeof(sb));
while(a){
sa[--na]=a%;
a/=;
}
while(b){
sb[--nb]=b%;
b/=;
}
REP(i,,m){
//cout<<sa[i]<<" "<<sb[i]<<endl;
if(sa[i]==sb[i])
return false;}
return true;
}
bool check2(int a){
int sa[],na=m+;
memset(sa,,sizeof(sa));
while(a){
sa[--na]=a%;
a/=;
}
REP(i,,m)
if(sa[i]==sa[i-])
return false;
return true;
}
void init(){
REP(i,,n){
if(i==k) continue;
tree[i].num=;
REP(j,,pow[m]-)
if(check2(j)){
tree[i].a[++tree[i].num]=j;
}
}
return ;
}
int DP(){
LL ans=;
REP(i,,tree[].num) f[][i]=;
REP(i,,n)
REP(j,,tree[i].num)
REP(k,,tree[i-].num)
if(check1(tree[i].a[j],tree[i-].a[k]))
{
f[i][j]=(f[i][j]+f[i-][k])%MOD;
}
REP(i,,tree[n].num) ans=(ans+f[n][i])%MOD;
return ans;
}
int main(){
pow[]=;
REP(i,,)
pow[i]=pow[i-]*;
in(n);in(m);in(k);
tree[k].num=;
REP(i,,m){
int x;
in(x);
x-=;
tree[k].a[]+=x*pow[m-i];
}
if(!check2(tree[k].a[])){
cout<<;
return ;
}
init();
/*REP(i,1,n){
REP(j,1,tree[i].num)
cout<<tree[i].a[j]<<" ";
cout<<endl;
}*/
cout<<DP()<<endl;
/*REP(i,1,n){
REP(j,1,tree[i].num)
cout<<f[i][j]<<" ";
cout<<endl;
}*/
return ;
}

Loj10172 涂抹果酱的更多相关文章

  1. LOJ#10172. 「一本通 5.4 练习 1」涂抹果酱

    题目链接:https://loj.ac/problem/10172 题目描述 Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕.蛋糕俯视图是一个 N×MN×MN×M 的矩形,它被划分成 ...

  2. loj#10172 涂抹果酱 (状压DP)

    题目: #10172. 「一本通 5.4 练习 1」涂抹果酱 解析: 三进制的状压DP 经过简单的打表发现,在\(m=5\)时最多有\(48\)种合法状态 然后就向二进制一样枚举当前状态和上一层的状态 ...

  3. 2018.09.10 loj#10172. 涂抹果酱(状压dp)

    传送门 三进制状压感觉有点难写啊. 不过这题状态转移方程挺简单的. 就直接f[i][j]表示前i行第i行状态为j时的选法总数,分情况转移就行了. 代码: #include<bits/stdc++ ...

  4. loj10172

    涂抹果酱 Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕.蛋糕俯视图是一个 N×M 的矩形,它被划分成 N×M 个边长为 1×1 的小正方形区域(可以把蛋糕当成 NNN 行 MMM  ...

  5. loj题目总览

    --DavidJing提供技术支持 现将今年7月份之前必须刷完的题目列举 完成度[23/34] [178/250] 第 1 章 贪心算法 √ [11/11] #10000 「一本通 1.1 例 1」活 ...

  6. CSU训练分类

    √√第一部分 基础算法(#10023 除外) 第 1 章 贪心算法 √√#10000 「一本通 1.1 例 1」活动安排 √√#10001 「一本通 1.1 例 2」种树 √√#10002 「一本通 ...

  7. YBT 5.4 状态压缩动态规划

    #loj 10170. 「一本通 5.4 例 1」骑士 看数据范围n<=10,所以不是搜索就是状压dp,又因为搜索会超时所以用dp dp[i][k][j]表示现已经放到第i行,前面共有k个,这一 ...

  8. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  9. 总结-一本通提高篇&算竞进阶记录

    当一个人看见星空,就再无法忍受黑暗 为了点亮渐渐沉寂的星空 不想就这样退役 一定不会鸽の坑 . 一本通提高篇 . 算竞进阶 . CDQ & 整体二分 . 平衡树 . LCT . 字符串 . 随 ...

随机推荐

  1. VC调用易语言DLL

    易语言方面: .版本 .子程序 show, , 公开 ' 本名称子程序用作测试程序用,仅在开发及调试环境中有效,编译发布程序前将被系统自动清空,请将所有用作测试的临时代码放在本子程序中. ***注意不 ...

  2. PHP开发-最简单的数据库操作,使用ezSQL

    PHP数据库操作使用ezSQL来实现,简单好用. 如果用的是mysql数据库,将下载的ezSQL文件中的mysql和shared连个文件夹拷贝到PHP工程目录中引用即可. 在PHP文件中 // Inc ...

  3. android 图片旋转 移动 放大缩小

    图片的变化主要是matrix的变化,对matrix不懂的可以先了解下matrxi. public class FunnyView extends View { /* * 手指按下时可能是移动 也可能是 ...

  4. bugku数字验证绕过正则

    题目:http://120.24.86.145:9009/21.php 第6行使用正则匹配如果匹配到$password开头12个字符中有空格则输出flag并执行exit; 12行是正则匹配$passw ...

  5. dm368 ipnc3.0环境搭建脚本

    前言 为了方便其他人搭建dm368 ipnc3.0环境,我写了个脚本,执行脚本就可以自动搭建好环境了,绝对的傻瓜操作了,不过有一个地方让我很郁闷,那就是在用sed替换掉某段内容的时候(143行--15 ...

  6. shell中$*与$@的区别

    $*所有的位置参数,被作为一个单词 注意:"$*"必须被""引用 $@ 与$*同义,但是每个参数都是一个独立的""引用字串,这就意味着参数被 ...

  7. 离线下载pip包进行安装【转】

    Host-A 不能上网,但是需要在上面安装Python-package 通过另外一台能上网的Host-B主机 1. 下载需要离线安装的Packages 在Host-B上执行如下命令: 安装单个Pack ...

  8. 修改 firefox accesskey 的快捷键

    Chrome中,如果设置了 accesskey 的话,可以通过 Alt + 快捷键 来之直接跳转的.但在Firefox 中,可能是为了防止于菜单的快捷键冲突,所以设置了 Shift + Alt + 快 ...

  9. HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...

  10. angular项目中使用angular-material2

    Step 1: Install Angular Material and Angular CDK npm install --save @angular/material @angular/cdk n ...