LOJ#10172. 「一本通 5.4 练习 1」涂抹果酱
题目链接: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」涂抹果酱相关推荐
- LOJ #10172. 「一本通 5.4 练习 1」涂抹果酱
题目描述 Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕.蛋糕俯视图是一个 N×M 的矩形,它被划分成 N×M 个边长为 1×1 的小正方形区域(可以把蛋糕当成 NNN 行 MMM ...
- #10172. 「一本通 5.4 练习 1」涂抹果酱 题解
题目链接 一道三进制状压的好题. 题目描述: Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕.蛋糕俯视图是一个 N×M的矩形,它被划分成 N×M个边长为 1×1的小正方形区域(可以把 ...
- #10172. 「一本通 5.4 练习 1」涂抹果酱 【 三进制状态压缩 】【 方案数 】
Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕.蛋糕俯视图是一个 N×M 的矩形,它被划分成 N×M 个边长为 1×1 的小正方形区域(可以把蛋糕当成 NNN 行 MMM 列的矩阵) ...
- Loj 10115 「一本通 4.1 例 3」校门外的树 (树状数组)
题目链接:https://loj.ac/problem/10115 题目描述 原题来自:Vijos P1448 校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的 ...
- 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] ...
- 数位dp(一)——Loj #10166. 「一本通 5.3 练习 1」数字游戏
题目链接:https://loj.ac/problem/10166 题目大意 求区间[a,b]有多少数字满足数位加和%N等于0. 解题思路 看范围,很明显的数位dp.我们设定状态dp[pos][N][ ...
- LOJ #10008. 「一本通 1.1 练习 4」家庭作业
智力大冲浪的数据加强版,n^2算法要被卡. 我们发现,原来的暴力代码最暴力的是这一段: for (register int j=num[i].pos; j>=1; --j) if (!f[j]) ...
- LOJ #10155. 「一本通 5.2 例 3」数字转换
无向图的最长链怎么求?和树的直径求法相同. #include <bits/stdc++.h> using namespace std; const int N=5e4+5; int n,a ...
- LOJ 10155. 「一本通 5.2 例 3」数字转换
题目:数字转换 思路: 对于每一个数,把它和它能够转移到的数之间连一条边. 由于不存在多元环,这个图本质上是一棵树. 然后在树上求最长链的长度就可以了. 具体实现就是dfs遍历整棵树,对于以每个点ii ...
最新文章
- android 8.0 intent,Android 8.0通知栏适配问题
- 微信公众平台JSSDK开发
- [LeetCode_5] Longest Palindromic Substring
- 云服务器虚拟主机区别,云服务器和虚拟主机的区别
- xpath 取标签下所有文字内容_xpath提取目录下所有标签内的内容,递归 //text()...
- Difference between Win-builds vs MinGW-builds
- ExtJS Grid中文字链接点击事件的更合理的处理办法
- python之用yagmail模块发送邮件
- MATLAB通信仿真实例1:无噪声信道下DSB-SC调制解调器
- WPF+prism框架实战源码和展示
- 知识图谱——关系抽取
- minitab怎么算西格玛水平_计算西格玛水平.ppt
- VGA、DVI、HDMI都是什么意思?
- oracle条件索引查询,Oracle复合索引用于范围查询条件
- 用计算机用鞋码算年龄,尺寸换算厘米对照(尺寸和厘米换算计算器)
- 网站广告的盈利模式详解
- 【python】身份证识别
- tensorflow的None下标、equal和consum函数总结
- SQL*Plus 系统变量之7 - BLO[CKTERMINATOR]
- 【GA三维路径规划】遗传算法无人机三维路径规划【含Matlab源码 1268期】
热门文章
- openEuler 20.03-LTS-SP3最小化安装
- janus是什么意思中文翻译_janus
- java毕业生设计在线培训课程网站管理系统计算机源码+系统+mysql+调试部署+lw
- Scoring Subsequences
- 嵌套走马灯Carousel
- PHP怎么设置字体走马灯效果,html跑马灯/走马灯效果
- 支付宝电脑网站支付及回调
- Windows纯净桌面实现
- 分享一下短视频创作者要掌握的短视频创作四个关键点
- ModuleNotFoundError: No module named ‘XXX ‘