思路来自FXXL中的某个链接

/*
CodeForces 840C - On the Bench [ DP ] | Codeforces Round #429 (Div. 1)
题意:
给出一个数组,问有多少种下标排列,使得任意两个相邻元素的乘积不是完全平方数
分析:
将数组分组,使得每组中的任意两个数之积为完全平方数
由唯一分解定理可知,每个质因子的幂次的奇偶性相同的两个数之积为完全平方数
即按每个质因子的幂次的奇偶性分组,故这样的分组唯一
然后问题归结于每组中的数不能相邻的排列有几种
设 dp[i][j]表示 前i组相邻的同组的数有j对
考虑把第i+1组分段后插入前i组的空隙中
枚举将下一组分成k段,每段相邻
枚举k段中有l段插在前面j对同组的空隙中
设前i组总个数为sum, 第i+1组个数为num
则得到转移方程
dp[i+1][j-l+num-k] += C(num-1, k-1) * C(j, l) * C(sum+1-j, k-l) * dp[i][j]
组合数什么的仔细推导下,再最后乘上每组的排列数
*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int MOD = 1e9+7;
const int N = 305;
LL C[N][N], F[N];
void init() {
C[0][0] = 1;
for (int i = 1; i < N; i++) {
C[i][0] = C[i][i] = 1;
for (int j = 1; j < i; j++)
C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
}
F[0] = 1;
for (int i = 1; i < N; i++) F[i] = i * F[i-1] % MOD;
}
bool check(LL a, LL b)
{
LL l = 1, r = 1e10, mid;
while (l <= r)
{
mid = (l+r) >> 1;
if (mid*mid <= a*b) l = mid+1;
else r = mid-1;
}
return r*r == a*b;
}
LL dp[N][N], ans;
int n, a[N], id[N], num[N], cnt;
void solve()
{
dp[0][0] = 1;
int sum = 0;
for (int i = 1; i <= cnt; i++)//第i组
{
for (int j = 0; j <= sum; j++)//j处平方
for (int k = 1; k <= num[i]; k++)//num[i]分成k段
for (int l = 0; l <= j && l <= k; l++)//j 中 l 段
{
LL tmp = dp[i-1][j];
tmp = tmp * C[num[i]-1][k-1] % MOD;
tmp = tmp * C[j][l] % MOD;
tmp = tmp * C[sum+1-j][k-l] % MOD;
dp[i][j-l+num[i]-k] += tmp;
dp[i][j-l+num[i]-k] %= MOD;
}
sum += num[i];
}
ans = dp[cnt][0];
for (int i = 1; i <= cnt; i++) ans = ans * F[num[i]] % MOD;
}
int main()
{
init();
cnt = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
bool flag = 0;
for (int j = 1; j < i; j++)
{
if (check(a[i], a[j]))
{
num[id[j]]++;
id[i] = id[j];
flag = 1; break;
}
}
if (!flag)
{
id[i] = ++cnt;
num[cnt] = 1;
}
}
solve();
printf("%lld\n", ans);
}

  

CodeForces 840C - On the Bench | Codeforces Round #429 (Div. 1)的更多相关文章

  1. CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)

    思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...

  2. CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)

    /* CodeForces 840A - Leha and Function [ 贪心 ] | Codeforces Round #429 (Div. 1) A越大,B越小,越好 */ #includ ...

  3. Codeforces Round #429 (Div. 2/Div. 1) [ A/_. Generous Kefa ] [ B/_. Godsend ] [ C/A. Leha and Function ] [ D/B. Leha and another game about graph ] [ E/C. On the Bench ] [ _/D. Destiny ]

    PROBLEM A/_ - Generous Kefa 题 OvO http://codeforces.com/contest/841/problem/A cf 841a 解 只要不存在某个字母,它的 ...

  4. Codeforces Round #429 (Div. 2) E. On the Bench

    E. On the Bench time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  5. Codeforces Round #429 (Div. 1) C. On the Bench(dp + 组合数)

    题意 一个长度为 \(n\) 的序列 \(A\) ,定义一个 \(1\) 到 \(n\) 的排列 \(p\) 是合法的,当且仅当 \(\forall i \in [1, n − 1], A_{p_i} ...

  6. 【做题】Codeforces Round #429 (Div. 2) E. On the Bench——组合问题+dp

    题目大意是给你n个数,求相邻两数相乘不是完全平方数的排列数. 一开始看到这题的时候,本人便想给相乘为完全平方数的数对建边,然后就写萎了... 后来通过集体智慧发现这个重要性质:对于自然数a,b,c,若 ...

  7. 【Codeforces Round #429 (Div. 2) A】Generous Kefa

    [Link]:http://codeforces.com/contest/841/problem/A [Description] [Solution] 模拟,贪心,每个朋友尽量地多给气球. [Numb ...

  8. 【Codeforces Round #429 (Div. 2) C】Leha and Function

    [Link]:http://codeforces.com/contest/841/problem/C [Description] [Solution] 看到最大的和最小的对应,第二大的和第二小的对应. ...

  9. 【Codeforces Round #429 (Div. 2) B】 Godsend

    [Link]:http://codeforces.com/contest/841/problem/B [Description] 两个人轮流对一个数组玩游戏,第一个人可以把连续的一段为奇数的拿走,第二 ...

随机推荐

  1. QT release版QAudioDeviceInfo获取不到音频设备,而debug版可以获取到

    新添加了两个模块:QCharts和Multimedia 但自己没有重新打包更新里面的库文件什么的... 坑爹... 害我找了这么久... 解决办法: 方法一: 将Qt安装目录下的plugins文件夹中 ...

  2. Hbuilder环境下配置php

    XAMPP的安装 https://blog.csdn.net/qing666888/article/details/81914389 安装并配置好Xampp后,在Hbuilder中下载php插件,工具 ...

  3. Python-04-数据结构

    一.数字 整数 Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等. 计算机由于使用二进制,所以,有时候用十六进制表示 ...

  4. Scratch编程:多彩的舞台(六)

    “ 上节课的内容全部掌握了吗?反复练习了没有,编程最好的学习方法就是练习.练习.再练习.一定要记得多动手.多动脑筋哦~~” 01 — 游戏介绍 这是一款简单的小游戏,实现了一个小女孩在多彩的舞台上进行 ...

  5. 理解javascript中的立即执行函数(function(){})()(转)

    原文:https://www.cnblogs.com/yanzp/p/6371292.html

  6. C++ 去掉字符串的首尾空格和全部空格

    #include <iostream>#include <string>using namespace std; //去掉收尾空格string& ClearHeadTa ...

  7. Python Unittest进行接口测试的简单示例

    今年肯定是要把Python学到一定程度的,否则感觉自己混不下去了,那就开始半挣扎的咸鱼生活吧. ---------------------------------------------------- ...

  8. 一行命令开启VNC 和windows之间复制粘贴功能

    sudo apt install autocutsel 安装完成之后: [注意]中文会乱码!!! 执行以下命令: autocutsel 这个则是后台运行,选择一种即可: autocutsel -f

  9. Android笔记(十六) 简易计算器

    实现功能: 简单计算器 布局及美化 采用LinearLayout嵌套LinearLayout实现布局. 要求 1. 按钮所有文字居于右下角 2. 按钮为白色,点击变成橘色 3. 显示屏文字居右显示并且 ...

  10. c# 字段成员