洛谷 P2476 [SCOI2008]着色方案

190 篇文章 2 订阅
84 篇文章 2 订阅

题面

题意

有n个木块,用k种颜色染色,每种油漆够染a[i]个,且a[i]之和为n,那么相邻两木块互不相同的染色方法有几种.

方法

此题难于记录状态,若用状态压缩则空间明显不够.
抓住每种颜色最多够刷5个木块且不一定要知道每一种颜色还剩下几个,可以开六位数组记录,前五个中,第i个记录剩余够刷i个木块的数量,最后一位记录上次用的颜色现在还够刷几个.
注意状态转移时,够刷i个的 -1 会使够刷i-1个的 +1.

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define D dp[a1][a2][a3][a4][a5][last]
#define M 1000000007
#define ll long long
using namespace std;

ll dp[20][20][20][20][20][5],ans;
int n,m,have[6];

ll dfs(int a1,int a2,int a3,int a4,int a5,int last)
{
    if(D!=-1) return D;
    if(!a1&&!a2&&!a3&&!a4&&!a5) return 1;
    ll res=0;
    if(a1) res+=(a1-(last==1))*dfs(a1-1,a2,a3,a4,a5,0),res%=M;
    if(a2) res+=(a2-(last==2))*dfs(a1+1,a2-1,a3,a4,a5,1),res%=M;
    if(a3) res+=(a3-(last==3))*dfs(a1,a2+1,a3-1,a4,a5,2),res%=M;
    if(a4) res+=(a4-(last==4))*dfs(a1,a2,a3+1,a4-1,a5,3),res%=M;
    if(a5) res+=(a5-(last==5))*dfs(a1,a2,a3,a4+1,a5-1,4),res%=M;
    D=res;
    return res;
}

int main()
{
    memset(dp,-1,sizeof(dp));
    register int i,j,p;
    cin>>m;
    for(i=1;i<=m;i++)
    {
        scanf("%d",&p);
        have[p]++;
    }
    cout<<dfs(have[1],have[2],have[3],have[4],have[5],0);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值