洛谷 2476 [SCOI2008]着色方案

50%的数据满足:1 <= k <= 5, 1 <= ci <= 3

100%的数据满足:1 <= k <= 15, 1 <= ci <= 5

【题解】

  本题中ci很小,因此可以直接5维保存可以涂i块的油漆有多少种颜色。然后利用乘法原理进行DP

  

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define LL long long
 4 #define rg register
 5 #define N 16
 6 #define Mod (1000000007)
 7 using namespace std;
 8 LL f[N][N][N][N][N][6];
 9 bool v[N][N][N][N][N][6];
10 int n,cnt[6];
11 inline int read(){
12     int k=0,f=1; char c=getchar();
13     while(c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar();
14     while(‘0‘<=c&&c<=‘9‘)k=k*10+c-‘0‘,c=getchar();
15     return k*f;
16 }
17 LL dfs(int a,int b,int c,int d,int e,int last){
18     if(v[a][b][c][d][e][last]) return f[a][b][c][d][e][last];
19     if(a+b+c+d+e==0) return 1;
20     LL tmp=0;
21     if(a) tmp+=(a-(last==2))*dfs(a-1,b,c,d,e,1);
22     if(b) tmp+=(b-(last==3))*dfs(a+1,b-1,c,d,e,2);
23     if(c) tmp+=(c-(last==4))*dfs(a,b+1,c-1,d,e,3);
24     if(d) tmp+=(d-(last==5))*dfs(a,b,c+1,d-1,e,4);
25     if(e) tmp+=e*dfs(a,b,c,d+1,e-1,5);
26     v[a][b][c][d][e][last]=1;
27     return f[a][b][c][d][e][last]=(tmp%Mod);
28 }
29 int main(){
30     n=read();
31     for(rg int i=1;i<=n;i++){
32         int x=read();
33         cnt[x]++;
34     }
35     printf("%lld\n",dfs(cnt[1],cnt[2],cnt[3],cnt[4],cnt[5],0));
36     return 0;
37 }

原文地址:https://www.cnblogs.com/DriverLao/p/8724370.html

时间: 2024-08-01 19:21:40

洛谷 2476 [SCOI2008]着色方案的相关文章

洛谷P2476 [SCOI2008]着色方案

题目:https://daniu.luogu.org/problemnew/show/P2476 题目背景 四川NOI省选第二试 题目描述 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i 种颜色的油漆足够涂ci 个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案. 输入输出格式 输入格式: 第一行为一个正整数k,第二行包含k个整数c1, c2, ... , ck. 输出

BZOJ 1079: [SCOI2008]着色方案 记忆化搜索

1079: [SCOI2008]着色方案 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=1079 Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的

[SCOI2008] 着色方案[高维dp]

321. [SCOI2008] 着色方案 ★★★   输入文件:color.in   输出文件:color.out   简单对比时间限制:1 s   内存限制:64 MB 题目背景: 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i 种颜色的油漆足够涂ci 个木块.所有油漆刚好足够涂满所有木块,即 c1+c2+...+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案.[输入]第一行为一个正整数k,第二行包含k个整数c1, c2,

bzoj1079: [SCOI2008]着色方案

ci<=5直接想到的就是5维dp了...dp方程YY起来很好玩...写成记忆化搜索比较容易 #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #

BZOJ 1079: [SCOI2008]着色方案 DP

1079: [SCOI2008]着色方案 Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案. Input 第一行为一个正整数k,第二行包含k个整数c1, c2, ... , ck. Output 输出一个整数,即方案总数模1,000,000,007的结果. Sample Inp

bzoj1079: [SCOI2008]着色方案(dp)

1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2133  Solved: 1287[Submit][Status][Discuss] Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案.

BZOJ 1079: [SCOI2008]着色方案(巧妙的dp)

BZOJ 1079: [SCOI2008]着色方案(巧妙的dp) 题意:有\(n\)个木块排成一行,从左到右依次编号为\(1\)~\(n\).你有\(k\)种颜色的油漆,其中第\(i\)种颜色的油漆足够涂\(c_i\)个木块.所有油漆刚好足够涂满所有木块,即\(\sum\limits _{i=1}^{k}c_i=n\).统计任意两个相邻木块颜色不同的着色方案.(\(1 \le k \le 15\) ,\(1\le c_i \le 5\)) 题解:特别巧妙的dp!一开始容易想到用\({c_i}^k

bzoj1079 [SCOI2008]着色方案

Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案. Input 第一行为一个正整数k,第二行包含k个整数c1, c2, ... , ck. Output 输出一个整数,即方案总数模1,000,000,007的结果. Sample Input 3 1 2 3 Sample Out

【BZOJ 1079】[SCOI2008]着色方案

Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案. Input 第一行为一个正整数k,第二行包含k个整数c1, c2, ... , ck. Output 输出一个整数,即方案总数模1,000,000,007的结果. Sample Input 3 1 2 3 Sample Out