Codeforces-840C On the Bench(dp)
来源:互联网 发布:v盾网络验证破解 编辑:程序博客网 时间:2024/06/04 01:21
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 < ncondition, that api·api + 1 is not perfect square, holds. Leha wants to find number of right permutations modulo 109 + 7.
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 single integer — number of right permutations modulo 109 + 7.
31 2 4
2
75 2 4 2 4 1 1
144
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.
题解:dp
将两两相乘等于完全平方数的数放入一组,设一共有sz组,每一组有cnt[i]个数
设dp[i][j]为当前一共放了i组数,有j对连续的数是同一组的(即其中需要插入某个不是同一组的数,一下称作间隙)
设k为将第i组数分成k+1份,则其中有cnt[i]-1-k个间隙
设p为从这k份中选p份插入间隙中,其它的不插入间隙
设m为前i组数一共有m+1个数字,有m个位置可以插入数字
dp[i][j+cnt[i]-1-k-p]=dp[i-1][j]*C(cnt[i]-1,k)*C(j,p)*C(m+2-j,k+1-p)
#include<bits/stdc++.h>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define x first#define y secondusing namespace std;typedef long long LL;typedef pair<int, int> PII;const int MX = 305;const LL mod = 1e9 + 7;LL dp[MX][MX], f[MX], invf[MX];LL pow(LL a, LL b) { LL ret = 1; while (b) { if (b & 1) ret = ret * a % mod; a = a * a % mod; b >>= 1; } return ret;}void init() { f[0] = 1; for (int i = 1; i < MX; i++) f[i] = f[i - 1] * i % mod; invf[MX - 1] = pow(f[MX - 1], mod - 2); for (int i = MX - 2; i >= 0; i--) invf[i] = invf[i + 1] * (i + 1) % mod;}LL C(int n, int m) { if (n < 0 || m < 0 || m > n) return 0; if (m == 0 || m == n) return 1; return f[n] * invf[n - m] % mod * invf[m] % mod;}bool check(LL x) { LL l = 1, r = 1e9; while (l <= r) { LL m = (l + r) >> 1; if (m * m == x) return 1; if (m * m < x) l = m + 1; else r = m - 1; } return 0;}LL a[305];int sz, cnt[MX], vis[MX];int main() { init(); int n; //freopen("in.txt", "r", stdin); scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%I64d", &a[i]); for (int i = 1; i <= n; i++) { if (vis[i]) continue; sz++; for (int j = i; j <= n; j++) { if (check(a[i]*a[j])) vis[j] = 1, cnt[sz]++; } } int m = cnt[1] - 1; dp[1][m] = 1; for (int i = 2; i <= sz; m += cnt[i++]) { for (int j = 0; j <= m; j++) {//dp[i-1][j] if (dp[i - 1][j] == 0) continue; for (int k = 0; k < cnt[i]; k++) {//分成k+1组,有a[i]-1-k个间隙 for (int p = 0; p <= min(k + 1, j); p++) { //插入p个间隙中 LL tmp = dp[i - 1][j] * C(cnt[i] - 1, k) % mod * C(j, p) % mod * C(m + 2 - j, k + 1 - p) % mod; (dp[i][j + cnt[i] - 1 - k - p] += tmp) %= mod; } } } } LL ans = dp[sz][0]; for (int i = 1; i <= sz; i++) ans = ans * f[cnt[i]] % mod; printf("%I64d\n", ans); return 0;}
- [DP] Codeforces 840C .On the Bench
- Codeforces-840C On the Bench(dp)
- Codeforces 840C On the Bench 【容斥+DP】
- codeforces 840C On the Bench 容斥+DP
- codeforces840C On the Bench -- DP
- codeforces 840 C. On the Bench(多重集合的交错排列经典题目)
- CF840C On the Bench(dp+组合数学)
- codeforces Simba on the Circle (dp)
- codeforces 505C Mr. Kitayuta, the Treasure Hunter(dp)
- Codeforces 689 C The Values You Can Make(dp)
- Codeforces-869C The Intriguing Obsession(DP/组合数)
- Codeforces 840C [DP]
- Codeforces 280C Game on Tree 树形期望dp
- codeforces 505C C. Mr. Kitayuta, the Treasure Hunter (dp)
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter(经典的DP)
- Codeforces 601C Kleofáš and the n-thlon(dp)
- Codeforces Round #358 (Div. 2) C Alyona and the Tree(树形DP)
- Codeforces Round #360 (Div. 1) C. The Values You Can Make(DP)
- [简单逻辑学]学习逻辑学的思想准备——避免闪避式语言
- linux 安装expect
- xlistview
- HTML5
- 广播监听网络状态
- Codeforces-840C On the Bench(dp)
- 2017 Multi-University Training Contest
- opencv中puttext()函数的使用
- 青蛙跳台阶/变态跳台阶问题
- pthread_create源码分析
- 20170822-BIN
- hdu 2063 过山车【二分图】
- bzoj 1138: [POI2009]Baj 最短回文路 bfs
- android TextView相关属性及文本处理