题目链接:https://loj.ac/problem/10172

题目描述

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

输入格式

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

输出格式

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

样例

样例输入

2 2
1
2 3

样例输出

3

样例说明

方案一 方案二 方案三
2 3\texttt{2 3}2 3 
1 2\texttt{1 2}1 2
2 3\texttt{2 3}2 3 
3 1\texttt{3 1}3 1
2 3\texttt{2 3}2 3 
3 2\texttt{3 2}3 2

数据范围与提示

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

题解

在网上找的题解,都不太清楚,让本蒟蒻卡了一下午加一晚上。

所以我弄懂以后,我就自己写了一篇,希望大家喜欢!

这道题是一道很好的状态压缩dp,因为有三种颜色,所以不能压成二进制,只能压成三进制。

当然啦,状压dp是基本一定要初始化的,别问我怎么知道的。

我们考虑以下两个初始化(就是代码里的pd1,pd2)

1. 每一行总共有很多种,但是因为相同颜色的果酱不能放在相邻的位置,所以每一行的不可行状态有很多。

这就需要预处理出一行中的可行状态。这样的话我们的dp数量会大大减少。

3. 预处理行与行之间的判断

跟预处理类似,减去不合法状态。

然后,就是我们的dp了。

其实这题很好想,dp[i][j]表示第i行的第j种状态,最后取个摸就行了。

方程:dp[i][j]+=dp[i-1][k]

最后的最后,大力推荐一下我的读入优化,跑的是真滴快!

#define num ch-'0'
inline void get(int &res)
{char ch;bool flag=0;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);for(res=num;isdigit(ch=getchar());res=res*10+num);(flag)&&(res=-res);
}

代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define MAXN 10010
#define mod 1000000
#define num ch-'0'
using namespace std;
inline int MAX(int a,int b){return a>b?a:b;}
inline int MIN(int a,int b){return a<b?a:b;}
inline void get(int &res)
{char ch;bool flag=0;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);for(res=num;isdigit(ch=getchar());res=res*10+num);(flag)&&(res=-res);
}
int n,g,m,k;
int dp[MAXN][250],ok[250][250];
int a[250],c[7],t;
inline int pd1(int x)
{for(register int i=m-1;i;--i)if((x%c[i+1])/c[i]==(x%c[i])/c[i-1]) return 0;return 1;
}
inline int pd2(int x,int y)
{for(register int i=m-1;i>=0;--i) if((x%c[i+1])/c[i]==(y%c[i+1])/c[i]) return 0;return 1;
}
int main()
{get(n),get(m),get(k);c[0]=1;int num1=0;for(register int i=1;i<=m;++i) {get(g);num1=num1*3+(g-1);c[i]=c[i-1]*3;}        if(!pd1(num1)) {puts("0");return 0;}for(register int i=0;i<c[m];++i){if(pd1(i)) a[++t]=i;if(num1==i) dp[0][t]=1;}for(register int i=1;i<=t;++i) for(register int j=1;j<=t;++j) ok[i][j]=pd2(a[i],a[j]);int res1=0,res2=0;int x=MIN(n-k,k-1),y=MAX(n-k,k-1);for(register int i=1;i<=y;++i) for(register int j=1;j<=t;++j) for(register int k=1;k<=t;++k) if(ok[k][j]) (dp[i][j]+=dp[i-1][k])%=mod;for(register int i=1;i<=t;++i) {res1=(res1+dp[x][i])%mod;res2=(res2+dp[y][i])%mod;}        printf("%lld",((long long)res2*res1)%mod);
}

转载于:https://www.cnblogs.com/mxrmxr/p/9807067.html

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

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

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

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

    题目链接 一道三进制状压的好题. 题目描述: Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕.蛋糕俯视图是一个 N×M的矩形,它被划分成 N×M个边长为 1×1的小正方形区域(可以把 ...

  3. #10172. 「一本通 5.4 练习 1」涂抹果酱 【 三进制状态压缩 】【 方案数 】

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

  4. Loj 10115 「一本通 4.1 例 3」校门外的树 (树状数组)

    题目链接:https://loj.ac/problem/10115 题目描述 原题来自:Vijos P1448 校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的 ...

  5. LOJ #10222. 「一本通 6.5 例 4」佳佳的 Fibonacci

    题目链接 题目大意 $$F[i]=F[i-1]+F[i-2]\ (\ F[1]=1\ ,\ F[2]=1\ )$$ $$T[i]=F[1]+2F[2]+3F[3]+...+nF[n]$$ 求$T[n] ...

  6. 数位dp(一)——Loj #10166. 「一本通 5.3 练习 1」数字游戏

    题目链接:https://loj.ac/problem/10166 题目大意 求区间[a,b]有多少数字满足数位加和%N等于0. 解题思路 看范围,很明显的数位dp.我们设定状态dp[pos][N][ ...

  7. LOJ #10008. 「一本通 1.1 练习 4」家庭作业

    智力大冲浪的数据加强版,n^2算法要被卡. 我们发现,原来的暴力代码最暴力的是这一段: for (register int j=num[i].pos; j>=1; --j) if (!f[j]) ...

  8. LOJ #10155. 「一本通 5.2 例 3」数字转换

    无向图的最长链怎么求?和树的直径求法相同. #include <bits/stdc++.h> using namespace std; const int N=5e4+5; int n,a ...

  9. LOJ 10155. 「一本通 5.2 例 3」数字转换

    题目:数字转换 思路: 对于每一个数,把它和它能够转移到的数之间连一条边. 由于不存在多元环,这个图本质上是一棵树. 然后在树上求最长链的长度就可以了. 具体实现就是dfs遍历整棵树,对于以每个点ii ...

最新文章

  1. android 8.0 intent,Android 8.0通知栏适配问题
  2. 微信公众平台JSSDK开发
  3. [LeetCode_5] Longest Palindromic Substring
  4. 云服务器虚拟主机区别,云服务器和虚拟主机的区别
  5. xpath 取标签下所有文字内容_xpath提取目录下所有标签内的内容,递归 //text()...
  6. Difference between Win-builds vs MinGW-builds
  7. ExtJS Grid中文字链接点击事件的更合理的处理办法
  8. python之用yagmail模块发送邮件
  9. MATLAB通信仿真实例1:无噪声信道下DSB-SC调制解调器
  10. WPF+prism框架实战源码和展示
  11. 知识图谱——关系抽取
  12. minitab怎么算西格玛水平_计算西格玛水平.ppt
  13. VGA、DVI、HDMI都是什么意思?
  14. oracle条件索引查询,Oracle复合索引用于范围查询条件
  15. 用计算机用鞋码算年龄,尺寸换算厘米对照(尺寸和厘米换算计算器)
  16. 网站广告的盈利模式详解
  17. 【python】身份证识别
  18. tensorflow的None下标、equal和consum函数总结
  19. SQL*Plus 系统变量之7 - BLO[CKTERMINATOR]
  20. 【GA三维路径规划】遗传算法无人机三维路径规划【含Matlab源码 1268期】

热门文章

  1. openEuler 20.03-LTS-SP3最小化安装
  2. janus是什么意思中文翻译_janus
  3. java毕业生设计在线培训课程网站管理系统计算机源码+系统+mysql+调试部署+lw
  4. Scoring Subsequences
  5. 嵌套走马灯Carousel
  6. PHP怎么设置字体走马灯效果,html跑马灯/走马灯效果
  7. 支付宝电脑网站支付及回调
  8. Windows纯净桌面实现
  9. 分享一下短视频创作者要掌握的短视频创作四个关键点
  10. ModuleNotFoundError: No module named ‘XXX ‘