CF840C On the Bench

题意翻译

给定\(n\) \((1≤n≤300)\) 个数,求问有多少种排列方案使得任意两个相邻的数之积都不是完全平方数。由于方案数可能很大,输出方案数 \(mod\) \(10^9+7\)的值。


首先每个数的每个质因子的幂可以先\(\bmod 2\),然后问题转化成两两不相等的方案数了。

证明也很简单,这些质因子的2次方是没有用的,洛谷的题解有一种更加美妙的方法进行了解释。

然后把每一组相等的数划分到一个集合里去。

设\(dp_{i,j}\)表示前\(i\)个集合有\(j\)对相等位置的排列数。

给出填表法的转移方程再进行具体解释

\(dp_{i,j+l-k}+=dp_{i-1,j} \times (fac_{ct} \times \binom{ct-1}{ct-1-l}) \times (\binom{j}{k} \times \binom{st+1-j}{ct-l-k})\)

两个括号的内容是独立考虑的,有些变量的意义慢慢说。


首先考虑第一个括号的内容

\(l\)表示第\(i\)个集合自身产生了\(l\)个相等的数,\(ct\)是第\(i\)个集合元素的个数,\(fac\)是阶乘

\(\binom{ct-1}{ct-1-l}\)表示把\(st\)个有序元素分成\(st-l\)个有序集合的方案数

可以从类似插板法的方法来说明,就是往空挡里面插东西。

因为这样的集合划分是有序的,而我们每个元素是可以无序的,所以乘上排列数,也就是阶乘。

所以第一个括号就是求出了把\(i\)这个集合分成了\(ct-l\)个集合的方案数,同时,Ta们是有序的。


第二个括号是把这\(ct-l\)个集合往空挡里面插的方案数。

\(k\)表示有\(k\)对相等的位置被插开了,\(st\)表示前\(i-1\)个集合的总元素个数

于是我们把这些东西分开的去插开别人或者不插开别人的方案数乘起来就可以了。


要枚举\(k\)和\(l\),复杂度说不清楚\(\text{QAQ}\)


Code:

#include <cstdio>
#include <algorithm>
#define ll long long
const int N=300;
const ll mod=1e9+7;
int a[N+10],b[N+10],cnt[N+10],tt[N+11],n,m;
ll C[N+10][N+10],dp[N+10][N+10],fac[N+10];
void init()
{
C[0][0]=1;
for(int i=1;i<=N;i++)
{
C[i][0]=1;
for(int j=1;j<=i;j++)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
}
fac[0]=1;
for(int i=1;i<=N;i++)
fac[i]=fac[i-1]*i%mod;
}
int min(int x,int y){return x<y?x:y;}
int main()
{
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",a+i);
for(int j=2;j*j<=a[i];j++)
while(a[i]%(j*j)==0) a[i]/=j*j;
}
std::sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
if(a[i]==b[m]) ++cnt[m],++tt[m];
else b[++m]=a[i],cnt[m]=1,tt[m]=tt[m-1]+1;
}
dp[1][cnt[1]-1]=fac[cnt[1]];
for(int i=1;i<m;i++)
for(int j=0;j<tt[i];j++)//相等个数
{
if(!dp[i][j]) continue;
for(int k=0;k<=min(j,cnt[i+1]);k++)//堵几个?
for(int l=0;l<=cnt[i+1]-k;l++)//搞几个?
{
if(j+l-k>=tt[i+1]||j+l-k<0) continue;
(dp[i+1][j+l-k]+=
dp[i][j]*C[j][k]%mod*
C[tt[i]+1-j][cnt[i+1]-l-k]%mod*
fac[cnt[i+1]]%mod*
C[cnt[i+1]-1][cnt[i+1]-1-l]%mod)%=mod;
}
}
printf("%lld\n",dp[m][0]);
return 0;
}

2018.10.15

CF840C On the Bench 解题报告的更多相关文章

  1. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  2. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  3. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  4. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  5. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  6. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

  7. 习题:codevs 1519 过路费 解题报告

    今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...

  8. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  9. LeetCode 解题报告索引

    最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中......                        ...

随机推荐

  1. spring-运行时值注入

    在项目中经常使用连接数据库的配置,如下所示 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDa ...

  2. 微信小程序图片上传

    uploadImage : function (){ wx.chooseImage({ count: 9, // 默认9 sizeType: ['original', 'compressed'], / ...

  3. admin添加用户时报错:(1452, 'Cannot add or update a child row: a foreign key constraint fails (`mxonline`.`django_admin_l

    在stackoverflow找到答案: DATABASES = { 'default': { ... 'OPTIONS': { "init_command": "SET ...

  4. 面试官常问的10个Linux问题

    1.如何暂停一个正在运行的进程,把其放在后台(不运行)? 为了停止正在运行的进程,让其再后台运行,我们可以使用组合键Ctrl+Z. 2.什么是安装Linux所需的最小分区数量,以及如何查看系统启动信息 ...

  5. 搭建cvs服务器

    http://zhangjunhd.blog.51cto.com/113473/78595 http://www.cnblogs.com/lee/archive/2008/10/22/1317226. ...

  6. 转MySQL详解--索引

    写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...

  7. 用命令部署WebPart

    Webpart一般是一个wsp文件,可以在VS里面通过右键来部署.但一般真正的生产服务器上面是不会安装VS的,所以一般情况下是把wsp文件拷贝到服务器上面然后启动PowerShell用命令来部署. 部 ...

  8. Python|花了一天,为大家整理的一套来自外国大佬的密码速查表

    简单的HTTPS服务器 检查证书信息 输出 生成自签名证书 输出 准备一个签名注册请求 输出 生成无密码的RSA秘钥文件 用一个私钥给文件签名 输出 从签名验证一个文件 输出 通过pem文件做RSA加 ...

  9. Linux通配符与特殊符号知识大全汇总

    符号 作用 Linux通配符 * 匹配任意(0个或多个)字符或字符串,包括空字符串 ? 匹配任意1个字符,有且只有一个字符 [abcd] 匹配abcd中任何一个字符,abcd也可是其他任意不连续字符 ...

  10. Leetcode 55. Jump Game & 45. Jump Game II

    55. Jump Game Description Given an array of non-negative integers, you are initially positioned at t ...