[DP] BZOJ1079: [SCOI2008]着色方案

题意

戳这里

题解

首先很容易想到,一开始可以把剩余使用次数相同的颜色归到一类考虑。
进一步思考,就可以根据这个想法来设计 DP 状态。
我们需要记一下现在剩余使用次数为1~5的颜色各有几种。转移的时候乘一个系数即可。
有关相邻颜色不同的限制,我们可以记一个上次涂的那种颜色现在的剩余使用次数,转移到那种次数的类时把系数减1即可。
很完美的合并了状态,使复杂度可以接受。
用记忆化dfs可以省去不合法状态,就能跑的很快了。

#include<cstdio>
#include<cstring> 
#include<algorithm>
using namespace std;
typedef long long LL;
const int MOD=1000000007;
int n,fst[6],f[5][16][16][16][16][16]; // 上次放的颜色现在还剩多少个, 剩 1,2,3,4,5 个的颜色分别有几个 

int get(int last,int t1,int t2,int t3,int t4,int t5){
    if(f[last][t1][t2][t3][t4][t5]!=-1) return f[last][t1][t2][t3][t4][t5];
    if(!(t1||t2||t3||t4||t5)) return 1;
    int res=0;
    if(t1) (res+=(LL)get(0,t1-1,t2,t3,t4,t5)*(t1-(last==1))%MOD)%=MOD;
    if(t2) (res+=(LL)get(1,t1+1,t2-1,t3,t4,t5)*(t2-(last==2))%MOD)%=MOD;
    if(t3) (res+=(LL)get(2,t1,t2+1,t3-1,t4,t5)*(t3-(last==3))%MOD)%=MOD;
    if(t4) (res+=(LL)get(3,t1,t2,t3+1,t4-1,t5)*(t4-(last==4))%MOD)%=MOD;
    if(t5) (res+=(LL)get(4,t1,t2,t3,t4+1,t5-1)*(t5-(last==5))%MOD)%=MOD;
    return f[last][t1][t2][t3][t4][t5]=res;
}
int main(){
    freopen("bzoj1079.in","r",stdin);
    freopen("bzoj1079.out","w",stdout);
    int t; scanf("%d",&t);
    while(t--){
        int x; scanf("%d",&x);
        n+=x; fst[x]++;
    }
    memset(f,255,sizeof(f));
    printf("%d\n",get(0,fst[1],fst[2],fst[3],fst[4],fst[5]));
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值