$有a_{1}个1,a_{2}个2,...,a_{n}个n(n<=15,a_{n}<=5),求排成一列相邻位不相同的方案数。$


关于这题的教训记录:

  • 学会对于复杂的影响分开计,善于发现整体变化,用整体法(没错就是和物理那种差不多)。
  • 推dp方程时怕边界问题不好处理时可以采用向前推的方法,就如$f[x]=f[i]+...$,可以(部分)避免越界。

我好菜啊。。除了个dp状态设计对了其他什么都没写上来qwq。基于每次插入时数字的数量都不固定,所以我可以设法将其固定下来。按顺序依次插入1,2,3,...,n即可。因为我是要统计相同不相邻方案,转移的时候肯定是插空啊,所以再设计一维表示有多少个相邻相同的($f[i][j]$),这样就好做了。然而我在这里卡主了。。因为我看数据每个数字最多5个嘛,分类大力讨论一下的事情。然而讨论到3的时候我已经崩溃掉了。觉得写法有问题,但是又不知道怎么简化。

磕了几小时没出来QwQ,翻了题解%%%,发现还是思路狭窄了啊。每个数k个,因为要往空挡里面插,不算几张合在一起的话,分开的情况是很容易想的。而我有连续数字插入的时候,可以枚举其分组。分k组的时候,这些牌单独来看是会产生出新的$n-k$个连续位的。再看我插入时,把连续数字当做整体(就是看成一个数字),插入之前的连续位空挡相当于把他填起来了,否则无影响。所以枚举插到数字$i$,枚举之前有$j$空位连续数字,当下分为$k$组,插到之前$j$个空位里的有$l$个,之前方案$f[i][j]$,$j$个空位中选出来$l$个是$C_{j}^{l}$,剩下的非连续数字的空位还要再选$C_{sum[i-1]+1-j}^{k-l}$个,这些空位里去填$k$组,问题转为一排数字划为k组的不同方案,是经典隔板问题,有$C_{a[i]-1}^{k-1}$种。所以dp方程就出来啦。见code。可以感性认识这是不重不漏的。(??!)

可能我组合计数还是太差了啊。几星期后到数学专题去好好补一发算了。。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define dddbg(x,y,z) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<" "<<#z<<" = "<<z<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const ll P=1e9+;
int f[][],fac[],C[][];
int T,n,s[],sum[];
inline void inc(int&A,int B){A+=B;A>=P?A-=P:;}
inline void preprocess(){
C[][]=;
for(register int i=;i<=;++i){C[i][]=;for(register int j=;j<=;++j)C[i][j]=(0ll+C[i-][j]+C[i-][j-])%P;}
} int main(){//freopen("test.in","r",stdin);freopen("test.out","w",stdout);
preprocess();read(n);
for(register int i=;i<=n;++i)read(s[i]);
f[][s[]-]=;
for(register int i=;i<=n;++i)sum[i]=s[i]+sum[i-];
for(register int i=;i<=n;++i)
for(register int j=;j<=sum[i-]-i+;++j)
for(register int k=;k<=s[i];++k)
for(register int l=;l<=_min(j,k);++l)
inc(f[i][j+s[i]-k-l],f[i-][j]*1ll*C[j][l]%P*C[sum[i-]+-j][k-l]%P*C[s[i]-][k-]%P);
printf("%d\n",f[n][]);
return ;
}

hihocoder扑克牌:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define dddbg(x,y,z) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<" "<<#z<<" = "<<z<<endl
using namespace std;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=;
ull f[N][],fac[],C[][];
int T,n,cnt[N],s[N],sum[N];
char ch[]; int main(){//freopen("test.in","r",stdin);freopen("test.out","w",stdout);
read(T);fac[]=,fac[]=,fac[]=,fac[]=;C[][]=;
for(register int i=;i<=;++i){
C[i][]=;
for(register int j=;j<=;++j)C[i][j]=C[i-][j]+C[i-][j-];
}
for(register int o=;o<=T;++o){
read(n);memset(cnt,,sizeof cnt);
for(register int i=;i<=n;++i){
scanf("%s",ch+);int x=ch[]&;
if(ch[]=='A')x=;else if(ch[]=='T')x=;else if(ch[]=='J')x=;else if(ch[]=='Q')x=;else if(ch[]=='K')x=;
++cnt[x];
}n=;
for(register int i=;i<=;++i)if(cnt[i])s[++n]=cnt[i],sum[n]=s[n]+sum[n-];
memset(f,,sizeof f);f[][s[]-]=;
for(register int i=;i<=n;++i)
for(register int j=;j<=sum[i-]-i+;++j)
for(register int k=;k<=s[i];++k)
for(register int l=;l<=_min(j,k);++l)
f[i][j+s[i]-k-l]+=f[i-][j]*C[j][l]*C[sum[i-]+-j][k-l]*C[s[i]-][k-];
for(register int i=;i<=n;++i)f[n][]*=fac[s[i]];
printf("Case #%d: %llu\n",o,f[n][]);
}
return ;
}

BZOJ1079 [SCOI2008]着色方案[组合计数DP]的更多相关文章

  1. BZOJ1079:[SCOI2008]着色方案(DP)

    Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个 ...

  2. BZOJ1079 [SCOI2008]着色方案 【dp记忆化搜索】

    题目 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难看 ...

  3. [luogu2476][bzoj1079][SCOI2008]着色方案【动态规划】

    题目描述 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难 ...

  4. BZOJ1079 [SCOI2008]着色方案 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1079 题目概括 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的 ...

  5. BZOJ1079: [SCOI2008]着色方案 (记忆化搜索)

    题意:有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很 ...

  6. 2018.10.20 bzoj1079: [SCOI2008]着色方案(多维dp)

    传送门 dp妙题. f[a][b][c][d][e][last]f[a][b][c][d][e][last]f[a][b][c][d][e][last]表示还剩下aaa个可以用一次的,还剩下bbb个可 ...

  7. bzoj1079: [SCOI2008]着色方案

    dp.以上次染色时用的颜色的数量和每种数量所含有的颜色作状态. #include<cstdio> #include<algorithm> #include<cstring ...

  8. 【记忆化搜索】bzoj1079 [SCOI2008]着色方案

    #include<cstring> #include<cstdio> using namespace std; #define MOD 1000000007 typedef l ...

  9. bzoj1079: [SCOI2008]着色方案

    ci<=5直接想到的就是5维dp了...dp方程YY起来很好玩...写成记忆化搜索比较容易 #include<cstdio> #include<cstring> #inc ...

随机推荐

  1. selenium+java+eclipse web项目自动化测试环境搭建

    一.java的安装与环境配置 1.下载JDK(Java Development Kit),下载地址 www.oracle.com 2.安装jdk(傻瓜式安装) 3.安装完成后,配置环境变量,步骤: ( ...

  2. LeetCode.1071-字符串最大公约数(Greatest Common Divisor of Strings)

    这是小川的第391次更新,第421篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第253题(顺位题号是1071).对于字符串S和T,当且仅当S = T + ... + T ...

  3. flask 框架快速入门

    flask 框架快速入门 搭建一个简易flask项目 首先使用 Pycharm创建flask项目 运行flask项目 1.使用Pycharm搭建flask项目 (如果Pycharm新建项目中未出现该图 ...

  4. python高级 之(三) --- 高阶函数

    高阶函数 map函数 简介 """ map(func,*iterables) 参数:一个是函数.一个是序列 作用:将序列中的元素依此作用于函数,将函数运行结果返回 存放于 ...

  5. PJzhang:crunch,一个很好的字典生成工具

    猫宁!!! 之前收集子域名的时候使用过子域名挖掘机这个windows软件,查看了它所使用的字典,基本上是小写字母数字1-4位的一个合集.   36+36*36+36*36*36+36*36*36*36 ...

  6. Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings)

    Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings) 给定两个字符串s1, s2,找到 ...

  7. 【Python开发】matplotlib绘图不显示问题解决plt.show()

    最近在看<Python数据分析>这本书,而自己写代码一直用的是Pycharm,在练习的时候就碰到了plot()绘图不能显示出来的问题.网上翻了一下找到知乎上一篇回答,试了一下好像不行,而且 ...

  8. VS2017:"64位调试操作花费的时间比预期要长",无法运行调试解决办法

    关于这个问题网上搜了好久,参考http://www.yishimei123.com/network/685.html这篇文章,最后终于解决了,在此表示非常感谢! 我的环境是:win10+VS2017 ...

  9. ASP.NET MVC Model 验证总结

    http://www.wyjexplorer.cn/Post/2012/8/3/model-validation-in-aspnet-mvc3 ASP.NET MVC3中的Model是自验证的,这是通 ...

  10. DNS 域名系统与邮件服务器

    目录 DNS 域名系统 定义 域名分类 解析流程 DNS分类 资源记录 格式 资源记录类型 用bind搭建一台DNS服务器 安装bind 创建自己的zone文件 在主配置文件中,增加自己的zone 检 ...