据说是能找到的题当中,最简单的三进制状压DP
题目大意
给n*m大的格子,n<=10000,m<=5,每相邻两个格子不能涂抹一样的颜色,一共有1,2,3这三种颜色,给出第k行每个格子涂抹的颜色,求总共有多少涂抹的方案。
对于那么小的一个m,我们很容易可以想到状压,但是颜色有三种,所以一般的二进制的状压显然是不可做的,这时候就要手写位运算搞个三进制的,把1到3分别记录成三进制下某一位的0到2,然后其实就看哪两个状态是可以相连的了,存下每种状态及可以相连的状态,易知正着和倒着其实是误差别的。
怎么说呢,我们现在把每一层压成一个数字,接下来的任务就是看合法的序列有多少种,以k为界限分开,上层和下层的方案数分别求出,然后相乘即为总方案数,上层下层互相无影响,所以直接乘法原理就ok了。
对于分层啥的,大概就是这样:
写出来代码就是
#include<bits/stdc++.h>
using namespace std;
#define Mod 1000000
int n,m,maxx,kn[250],k,ans1,ans2,tot,len[250],hh[250][250],f[10010][250],a,lp,ans;
bool jiance(int x)//检测状态本身是否合法
{
int num=m-1;
while(num--)
{
if(x