#线性dp,排列组合#洛谷 2476 [SCOI2008]着色方案
分析(弱化版)
最暴力的想法就是直接维护每种颜色的个数dp,
弱化版有一个很突出的地方就是 \(c_i\leq 5\),
也就是说可以将相同个数的颜色合并按照个数dp,
设 \(dp[c1][c2][c3][c4][c5][las]\) 表示个数为 \(i\) 的颜色有 \(ci\) 种,并且上一次选了个数为 \(las\) 的颜色的方案数
也就是这次如果选了 \(las-1\) 要减掉一个相邻的情况,转移可以记忆化。
代码
#include <cstdio>
using namespace std;
const int N=16,mod=1000000007;
int n,c[5],dp[N][N][N][N][N][5],ans;
int mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int Dp(int c0,int c1,int c2,int c3,int c4,int las){
if (dp[c0][c1][c2][c3][c4][las]) return dp[c0][c1][c2][c3][c4][las];
int ans=0;
if (c0) ans=mo(ans,1ll*(c0-(las==1))*Dp(c0-1,c1,c2,c3,c4,0)%mod);
if (c1) ans=mo(ans,1ll*(c1-(las==2))*Dp(c0+1,c1-1,c2,c3,c4,1)%mod);
if (c2) ans=mo(ans,1ll*(c2-(las==3))*Dp(c0,c1+1,c2-1,c3,c4,2)%mod);
if (c3) ans=mo(ans,1ll*(c3-(las==4))*Dp(c0,c1,c2+1,c3-1,c4,3)%mod);
if (c4) ans=mo(ans,1ll*(c4-(las==5))*Dp(c0,c1,c2,c3+1,c4-1,4)%mod);
return dp[c0][c1][c2][c3][c4][las]=ans;
}
int main(){
scanf("%d",&n);
for (int i=1,x;i<=n;++i)
scanf("%d",&x),++c[x-1];
for (int i=0;i<5;++i) dp[0][0][0][0][0][i]=1;
if (c[0]) ans=mo(ans,1ll*c[0]*Dp(c[0]-1,c[1],c[2],c[3],c[4],0)%mod);
if (c[1]) ans=mo(ans,1ll*c[1]*Dp(c[0]+1,c[1]-1,c[2],c[3],c[4],1)%mod);
if (c[2]) ans=mo(ans,1ll*c[2]*Dp(c[0],c[1]+1,c[2]-1,c[3],c[4],2)%mod);
if (c[3]) ans=mo(ans,1ll*c[3]*Dp(c[0],c[1],c[2]+1,c[3]-1,c[4],3)%mod);
if (c[4]) ans=mo(ans,1ll*c[4]*Dp(c[0],c[1],c[2],c[3]+1,c[4]-1,4)%mod);
return !printf("%d",ans);
}
分析(加强版)
在牛客的题目里,\(k,c_i\leq 30\),似乎有点棘手,考虑一个一个颜色填入序列。
设 \(dp[i][j]\) 表示前 \(i\) 种颜色有 \(j\) 个相邻的同色块的方案数。
枚举将这种颜色分成 \(k\) 段,以及选择 \(o\) 段破坏原来的相邻的同色块。那么
\]
代码
#include <cstdio>
#include <cctype>
#include <cstring>
using namespace std;
const int N=31,M=911,mod=1000000007;
int a[N],s[N],c[M][M],dp[N][M],n;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int main(){
c[0][0]=1;
for (int i=1;i<M;++i){
c[i][0]=c[i][i]=1;
for (int j=1;j<i;++j)
c[i][j]=mo(c[i-1][j-1],c[i-1][j]);
}
for (int T=iut();T;--T){
n=iut();
for (int i=1;i<=n;++i) a[i]=iut(),s[i]=s[i-1]+a[i];
memset(dp,0,sizeof(dp)),dp[1][a[1]-1]=1;
for (int i=2;i<=n;++i)
for (int j=0;j<=s[i-1];++j)
if (dp[i-1][j]){
for (int k=1;k<=a[i];++k) for (int o=0;o<=k&&o<=j;++o)
dp[i][j+a[i]-k-o]=mo(dp[i][j+a[i]-k-o],1ll*dp[i-1][j]*c[a[i]-1][k-1]%mod*c[s[i-1]+1-j][k-o]%mod*c[j][o]%mod);
}
printf("%d\n",dp[n][0]);
}
return 0;
}
#线性dp,排列组合#洛谷 2476 [SCOI2008]着色方案的更多相关文章
- BZOJ1079或洛谷2476 [SCOI2008]着色方案
一道记忆化搜索 BZOJ原题链接 洛谷原题链接 发现对于能涂木块数量一样的颜色在本质上是一样的,所以可以直接压在一个状态,而这题的数据很小,直接暴力开\(6\)维. 定义\(f[a][b][c][d] ...
- 洛谷 2476 [SCOI2008]着色方案
50%的数据满足:1 <= k <= 5, 1 <= ci <= 3 100%的数据满足:1 <= k <= 15, 1 <= ci <= 5 [题解] ...
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas
[题目]BZOJ 2111 [题意]求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果.\(n \leq 10^6,p \leq 10^9\),p是素数 ...
- 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值
[题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ...
- G.subsequence 1(dp + 排列组合)
subsequence 1 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 You are ...
- 洛谷P2756飞行员配对方案问题 P2055假期的宿舍【二分图匹配】题解+代码
洛谷 P2756飞行员配对方案问题 P2055假期的宿舍[二分图匹配] 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架 ...
- bzoj 1079: [SCOI2008]着色方案 DP
1079: [SCOI2008]着色方案 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 803 Solved: 512[Submit][Status ...
- [SCOI2008] 着色方案[高维dp]
321. [SCOI2008] 着色方案 ★★★ 输入文件:color.in 输出文件:color.out 简单对比时间限制:1 s 内存限制:64 MB 题目背景: 有n个木块排成一 ...
- BZOJ 1079: [SCOI2008]着色方案 记忆化搜索
1079: [SCOI2008]着色方案 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
随机推荐
- win32 - 匿名管道的使用
目标: 创建一个父进程和子进程,在子进程的控制台窗口输入数据,数据通过管道发送给父进程,父进程的控制台窗口读取数据,最后将数据打印出来. Parent.cpp //CMD.exe #include & ...
- 学习go语言编程之面向对象
类型系统 类型系统是指一个语言的类型体系结构,一个典型的类型系统通常包含如下基本内容: 基础类型,如:byte.int.bool.float等 复合类型,如:数组.结构体.指针等 可以指向任意对象的类 ...
- Linux驱动开发笔记(三):基于ubuntu的helloworld驱动源码编写、makefile编写以及驱动编译加载流程测试
前言 前面学习了驱动的基础框架,上一篇编译了gcc7.3.0,那么为了方便很好的熟悉流程,本篇,将使用ubuntu18.04,直接编译ubuntu18.04的驱动,然后做好本篇文章的相关实战测试. ...
- 面向对象之封装,类的相关操作,私有成员删除,构造方法__init__---day20
1.面向对象之封装 # ### 面向对象oop -封装 """ 类中封装: 成员属性 成员方法 封装等级: 1.公有:公有成员既能够在类外调用,也可在类内调用 2.私有: ...
- 【LeetCode二叉树#10】从中序与后序(或者前序)遍历序列构造二叉树(首次构造二叉树)
从中序与后序遍历序列构造二叉树 力扣题目链接(opens new window) 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorde ...
- Windows NFS 真弱 → 中文乱码导致文件找不到
开心一刻 正睡着觉,然后来了个电话 对方说:你好,方便面是吗 我愣了一下,以为是恶作剧 回了句:我不是,我是火腿肠! 就挂了电话 又躺了好一会,忽然琢磨过来...... 不对呀,她好像说的是:你好,方 ...
- Find The Multiple 题解
Find The Multiple The long-lost Sunday is coming again, and the ACM Laboratory Elimination Competi ...
- C# DiagnosticSource and DiagnosticListener
class Program { private static readonly DiagnosticSource testDiagnosticListener = new DiagnosticList ...
- Java/Kotlin 密码复杂规则校验
原文地址: Java/Kotlin 密码复杂度校验 | Stars-One的杂货小窝 每次有那个密码复杂校验,不会写正则表达式,每次都去搜,但有时候校验的条件又是奇奇怪怪的,百度都搜不到 找到了个代码 ...
- iBatis查询API
"一切皆Socket!" 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. --有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信 ...