CodeForces 840C - On the Bench | Codeforces Round #429 (Div. 1)
思路来自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)的更多相关文章
- CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)
思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...
- CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)
/* CodeForces 840A - Leha and Function [ 贪心 ] | Codeforces Round #429 (Div. 1) A越大,B越小,越好 */ #includ ...
- 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 解 只要不存在某个字母,它的 ...
- 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 ...
- Codeforces Round #429 (Div. 1) C. On the Bench(dp + 组合数)
题意 一个长度为 \(n\) 的序列 \(A\) ,定义一个 \(1\) 到 \(n\) 的排列 \(p\) 是合法的,当且仅当 \(\forall i \in [1, n − 1], A_{p_i} ...
- 【做题】Codeforces Round #429 (Div. 2) E. On the Bench——组合问题+dp
题目大意是给你n个数,求相邻两数相乘不是完全平方数的排列数. 一开始看到这题的时候,本人便想给相乘为完全平方数的数对建边,然后就写萎了... 后来通过集体智慧发现这个重要性质:对于自然数a,b,c,若 ...
- 【Codeforces Round #429 (Div. 2) A】Generous Kefa
[Link]:http://codeforces.com/contest/841/problem/A [Description] [Solution] 模拟,贪心,每个朋友尽量地多给气球. [Numb ...
- 【Codeforces Round #429 (Div. 2) C】Leha and Function
[Link]:http://codeforces.com/contest/841/problem/C [Description] [Solution] 看到最大的和最小的对应,第二大的和第二小的对应. ...
- 【Codeforces Round #429 (Div. 2) B】 Godsend
[Link]:http://codeforces.com/contest/841/problem/B [Description] 两个人轮流对一个数组玩游戏,第一个人可以把连续的一段为奇数的拿走,第二 ...
随机推荐
- 往List集合循环add(对象)得到的是重复对象
记录每次的错误,强大是慢慢的积累,先看看代码, 往list中循环添加RoleKungFu对象,看似没有问题,结果打印则显示: 全部是重复的数据!这是因为啥呢,因为将对象add入list中时,放入lis ...
- oauth2 + jwt 实现用户中心
由于公司项目比较杂,以前都是各产品线自行完成注册和登入.随着产品迭代,需要一个用户中心统一用户的管理,写个博客做个记录. 用oauth2实现,jwt作为token生成. oauth2流程图: user ...
- Ubuntu 软件卸载脚本(卸载软件 + 移除配置文件 + 移除依赖项)
#!/bin/bash function z-apt-uninstall() { if [ ! $1 ] then echo "z-apt-uninstall error: software ...
- Python——继承
Python的继承是多继承机制,一个子类可以同时有多个直接父类:继承可以得到父类定义的方法,子类就可以复用父类的方法. 一.继承的语法 子类:实现继承的类. 父类(基类.超类):被继承的类. 子类继承 ...
- PAT(B) 1077 互评成绩计算(Java)
题目链接:1077 互评成绩计算 (20 point(s)) 题目描述 在浙大的计算机专业课中,经常有互评分组报告这个环节.一个组上台介绍自己的工作,其他组在台下为其表现评分.最后这个组的互评成绩是这 ...
- adb连接安卓设备的2种方式
一.usb连接 安卓设备打开开发者模式,启用usb调试 CMD窗口输入adb devices,此时可以看到自己的设备 PS:无法看到自己设备时,查看手机USB调试是否打开:PC端是否安装手机驱动. 二 ...
- Java基础IO类之字节数组流
package IODemo; //字节数组流 :内部维护这着一个字节数组,我们可以利用流的读取机制来处理字符串 无需关闭,不会报IO异常 // ByteArrayInputstream ByteAr ...
- javascript之防抖与节流
防抖 你是否在日常开发中遇到一个问题,在滚动事件中需要做个复杂计算或者实现一个按钮的防二次点击操作. 这些需求都可以通过函数防抖动来实现.尤其是第一个需求,如果在频繁的事件回调中做复杂计算,很有可能导 ...
- 如何加入 Skype for Business 会议?
参加一个线上培训,收到了Skype的参会地址,是这个样子的 然后就是一脸懵逼的不知道怎么参加会议了.找了半天终于在同事的帮助下参加成功. 我的参加方法:在Window上用Skype for Busin ...
- ajax中的事件
blur : 当光标移开时(点击)触发 change : 当光标移开并且文本框中的内容和上一次不一致时(点击)触发