NC20265 着色方案(dp)

这题我的第一想法是维护每个颜色的个数,然后记忆化搜索

但是这个有15个,实在维护不了,但是我们可以转化思路看看

其实只需要相临的关系看着,其他前面的无所谓,我们就维护一下每个大小有哪几个就行,额外再维护上一个点的颜色即可,因为需要取一下重,两次不能一个颜色

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int a[N];
ll f[16][16][16][16][16][6];
ll dfs(int a,int b,int c,int d,int e,int last){
    if(a+b+c+d+e==0)
        return 1;
    auto &x=f[a][b][c][d][e][last];
    if(x!=-1)
        return x;
    ll res=0;
    if(a) res=(res+(a-(last==2))*dfs(a-1,b,c,d,e,1))%mod;
    if(b) res=(res+(b-(last==3))*dfs(a+1,b-1,c,d,e,2))%mod;
    if(c) res=(res+(c-(last==4))*dfs(a,b+1,c-1,d,e,3))%mod;
    if(d) res=(res+(d-(last==5))*dfs(a,b,c+1,d-1,e,4))%mod;
    if(e) res=(res+e*dfs(a,b,c,d+1,e-1,5))%mod;
    return x=res;
}
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    for(i=1;i<=n;i++){
        int x;
        cin>>x;
        a[x]++;
    }
    memset(f,-1,sizeof f);
    cout<<dfs(a[1],a[2],a[3],a[4],a[5],0)<<endl;
    return 0;
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/14427396.html