P2476 [SCOI2008]着色方案(记搜&多维dp)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2476 [SCOI2008]着色方案(记搜&多维dp)相关的知识,希望对你有一定的参考价值。
P2476 [SCOI2008]着色方案(记搜&多维dp)
因为每种颜色至多 5 5 5个。
考虑按照个数分类。
然后令 f ( a , b , c , d , e , l a s t ) f(a,b,c,d,e,last) f(a,b,c,d,e,last)
表示个数为 1 1 1的颜色种类、个数为 2 2 2的颜色种类 … \\dots …, l a s t last last表示上一次选择的颜色是个数为 l a s t last last的。
然后考虑如何转移:若选择个数为1的,则由 ( a − ( l a s t = = 2 ) ) × f ( a − 1 , b , c , d , e , 1 ) (a-(last==2))\\times f(a-1,b,c,d,e,1) (a−(last==2))×f(a−1,b,c,d,e,1)转移。
这里要判断是否 l a s t = = 2 last==2 last==2,因为如果上一次选择 l a s t = 2 last=2 last=2,则说明上一次的颜色是 a a a个中的一种,不能选择颜色相同连续的。
所以 ( a − 1 ) (a-1) (a−1)。
其他依次类推。
时间复杂度: O ( 5 × 1 5 5 ) O(5\\times 15^5) O(5×155)
// Problem: P2476 [SCOI2008]着色方案
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2476
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-08-25 13:44:17
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=16,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
ll f[N][N][N][N][N][6];
ll dfs(int a,int b,int c,int d,int e,int last){
ll & s = f[a][b][c][d][e][last];
//printf("(%d,%d,%d,%d,%d)\\n",a,b,c,d,e);
if(~s) return s;
if(a+b+c+d+e==0) return 1;
s=0;
if(a) s+=(a-(last==2))*dfs(a-1,b,c,d,e,1);
if(b) s+=(b-(last==3))*dfs(a+1,b-1,c,d,e,2);
if(c) s+=(c-(last==4))*dfs(a,b+1,c-1,d,e,3);
if(d) s+=(d-(last==5))*dfs(a,b,c+1,d-1,e,4);
if(e) s+=e*dfs(a,b,c,d+1,e-1,5);
return s%=mod;
}
int c[6];
int main(){
int n;scanf("%d",&n);while(n--){
int x;scanf("%d",&x);c[x]++;
}
mst(f,-1);
printf("%lld\\n",dfs(c[1],c[2],c[3],c[4],c[5],0));
return 0;
}
以上是关于P2476 [SCOI2008]着色方案(记搜&多维dp)的主要内容,如果未能解决你的问题,请参考以下文章