题面

传送门:http://codeforces.com/problemset/problem/840/C
C. On the Bench
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
A year ago on the bench in public park Leha found an array of n numbers. Leha believes that permutation p is right if for all 1 ≤ i < n condition, that api·api + 1 is not perfect square, holds. Leha wants to find number of right permutations modulo 109 + 7.

Input
First line of input data contains single integer n (1 ≤ n ≤ 300) — length of the array.

Next line contains n integers a1, a2, … , an (1 ≤ ai ≤ 109) — found array.

Output
Output single integer — number of right permutations modulo 109 + 7.

Examples
inputCopy
3
1 2 4
outputCopy
2
inputCopy
7
5 2 4 2 4 1 1
outputCopy
144
Note
For first example:

[1, 2, 4] — right permutation, because 2 and 8 are not perfect squares.

[1, 4, 2] — wrong permutation, because 4 is square of 2.

[2, 1, 4] — wrong permutation, because 4 is square of 2.

[2, 4, 1] — wrong permutation, because 4 is square of 2.

[4, 1, 2] — wrong permutation, because 4 is square of 2.

[4, 2, 1] — right permutation, because 8 and 2 are not perfect squares.
中文题目大意:
给出n个正整数数,求将n个数排列成相邻两个数之积不是完全平方数的序列的方法数,结果模1000000007

分析

此题是一道综合性题目,考察了DP,组合数学和数论知识
我们先从DP入手
在DP之前,要做一个预处理,将n个数分成size组,每组中的数相乘为完全平方数,与其他数乘起来不能得到完全平方数的数单独一组
如1 4 2 5 9 可以分为{1.4.9},{2},{5}三组

接着开始推导DP方程
分解子状态:设dp[i][j] 表示前i组数中有j个不合法的数对时的方法数(一个不合法数对即两个数乘起来是完全平方数,如1,9)
设第i组有cnt个数,前i组一共有sum个数
第i组数的顺序可以任意排列,有cnt!种排法
我们将第i组分为k段,则产生了k个不合法的序列,分为s段的方法数为C(cnt-1,k-1) .可以这样想象,在第i组数中间的cnt-1个间隔中,插入k-1个隔板,把cnt个数分为k段

从前面j个数对不合法的中选p个数对,有C(j,p)种方法,将k组数中的p组插入到数对中,使每个数对中间有一组数,这样就消除了p个不合法数对
如数对(1,4) 可以用插入数对(5,20)来消除
数列变成5,1,20,4

k组数中的另外(k-p)组数则另外选位置插入。在sum+1个可插入的位置(头尾也可以插入),原来不合法的j个空缺不能插入,因此只能插入到sum+1-j个位置,有C(sum+1-j,k-p)种方法,这s-p组数本身是不合法的。
原本这cnt个数连续排在一起是不合法的,会产生cnt-1个不合法数对,但我们用k-1个隔板隔开后,有k-1个位置变成合法的了,每组数因此又会产生cnt-k个不合法位置
如:1 4 9 ,分为{1,4},{9}插入到序列A,B,C中
A 1 4 B 9 C ,有1个位置不合法,即1,4

这样插入过后,消除了p个不合法数对,新增了cnt-k个不合法数对,总不合法数对个数为j-p+cnt-k个
于是我们就实现了从dp[i-1][j]到dp[j-p+cnt-k]的转移
状态转移方程为:
dp[i][j−p+cnt−k]=dp[i][j−p+cnt−k]+cnt!×dp[i−1][j]×Ck−1cnt−1×Cpj×Ck−psum+1−jdp[i][j−p+cnt−k]=dp[i][j−p+cnt−k]+cnt!×dp[i−1][j]×Ccnt−1k−1×Cjp×Csum+1−jk−p

Codeforces 840C 题解(DP+组合数学)的更多相关文章

  1. Codeforces 691E题解 DP+矩阵快速幂

    题面 传送门:http://codeforces.com/problemset/problem/691/E E. Xor-sequences time limit per test3 seconds ...

  2. Codeforces 833B 题解(DP+线段树)

    题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...

  3. Codeforces 984D 题解(DP)

    题面 传送门 题目大意: 给你一个计算区间f函数的公式,举例f(1,2,4,8)=f(1⊕2,2⊕4,4⊕8)=f(3,6,12)=f(3⊕6,6⊕12)=f(5,10)=f(5⊕10)=f(15)= ...

  4. [CQOI2011]放棋子 题解(dp+组合数学)

    Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数. 第二行包含c个正整数,即每个颜色的棋子数. 所有颜色的棋子总数保证不超过nm. N,M<=3 ...

  5. CodeForces 840C - On the Bench | Codeforces Round #429 (Div. 1)

    思路来自FXXL中的某个链接 /* CodeForces 840C - On the Bench [ DP ] | Codeforces Round #429 (Div. 1) 题意: 给出一个数组, ...

  6. CF_229E_Gift_概率DP+组合数学

    CF_229E_Gift_概率DP+组合数学 题目描述: 很久很久以前,一位老人和他的妻子住在蔚蓝的海边.有一天,这位老人前去捕鱼,他捉到了一条活着的金鱼.鱼说:“噢,老渔人!我祈求你放我回到海里,这 ...

  7. [多校联考2019(Round 5 T3)]青青草原的表彰大会(dp+组合数学)

    [多校联考2019(Round 5)]青青草原的表彰大会(dp+组合数学) 题面 青青草原上有n 只羊,他们聚集在包包大人的家里,举办一年一度的表彰大会,在这次的表彰大会中,包包大人让羊们按自己的贡献 ...

  8. [FJOI2007]轮状病毒 题解(dp(找规律)+高精度)

    [FJOI2007]轮状病毒 题解(dp(找规律)+高精度) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1335733 没什么好说的,直接把规律找出来,有 ...

  9. [Codeforces722E] Research Rover (dp+组合数学)

    [Codeforces722E] Research Rover (dp+组合数学) 题面 给出一个N*M的方格阵,从(1,1)出发,到(N,M)结束,从(x,y)只能走到(x+1,y)或(x,y+1) ...

随机推荐

  1. bzoj3011 [Usaco2012 Dec]Running Away From the Barn 左偏树

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3011 题解 复习一下左偏树板子. 看完题目就知道是左偏树了. 结果这个板子还调了好久. 大概已 ...

  2. vue开发知识点总结

    一.vue介绍 Vue.js 是一套构建用户界面(UI)的渐进式JavaScript框架,是一个轻量级MVVM(model-view-viewModel)框架. 二.数据绑定 最常用的方式:Musta ...

  3. 在Wi-Fi路由器中发现了新的安全漏洞

    黑客利用两种互联网通用协议的互动的漏洞:传输控制协议,或TCP和Wi-Fi.该漏洞利用并不针对任何传统的安全漏洞.相反,安全方面的弱点在于20多年前制定的基本Wi-Fi设计决策极难改变. 中国黑客教父 ...

  4. python的setup.py文件

    最近工作需要,用Cython写了*.pyx扩展,并将其编译成C文件,最后转换为so扩展,供python引用使用 distutils 编译,建立一个setup.py 的脚本from distutils. ...

  5. iView栅格的使用

    一般情况下栅格系统都会把每行row分为12列,但是iview是采用了24栅格系统,将区域进行24等分 基础用法 实例代码: <template> <Row> <Col s ...

  6. React Native 中 跨页面间通信解决方案之 react-native-event-bus

    https://github.com/crazycodeboy/react-native-event-bus 用法: A页面和B页面中都有相同的列表,点击B页面中的收藏按钮,A页面会跟着更新 impo ...

  7. React 之React.createContext

    使用Context,可以跨越组件进行数据传递 import React from 'react'; import ReactDOM from 'react-dom'; const ThemeConte ...

  8. #431 Div2 Problem B Tell Your World (鸽巢原理 && 思维)

    链接 : http://codeforces.com/contest/849/problem/B 题意 : 给出 n 个在直角坐标系上的点,每个点的横坐标的值对应给出的顺序序数,比如 1 2 4 3 ...

  9. 简单的LCA

    这么久了才做LCA的题,以前是感觉很难不敢去尝试,现在学习了一番之后发现算法本身并不难.... 学习时看了这篇博文:https://www.cnblogs.com/JVxie/p/4854719.ht ...

  10. android中使用Application

    在android开发过程中,我们可能存储一些全局的变量,最好在正在app的任何一个activity或者service中都可以访问到,这时我们可以使用application. 我们的一个应用就叫appl ...