hihocoder 1505
题意:给你n个数,让你从n个数中抽两个数,再抽两个数,使得前两个数和后两个数相等
分析:对 i,j,p,q遍历的话时间复杂度会达到o(n4),所以考虑优化p,q
假设分配给小hi的金币为 a[i]和a[j],现在的问题是求剩下的元素中有多少组 p, q 使得 a[i] + a[j] = a[p] + a[q]。如果暴力枚举所有可能的 p, q,需要 O(n^2)时间,再加上枚举i, j 的时间,时间复杂度是 O(n^4),会超时。所以不能枚举 p, q。
把输入保存在数组 a[] 中。
令 sumCnt[x] 表示两袋金币之和 a[i] + a[j] = x 组合数。
令 cnt[y] 表示元素 y 出现的次数。
假设分配给小hi的金币为 x = a[i] + a[j],那么x一共有 sumCnt[x] 种可能的组合。
令 c1 = cnt[a[i]], c2 = cnt[a[j]],
假设 a[i] != a[j]。
去掉a[i], a[j]之前,a[i]和a[j]一共可以组成 c1 * c2个 x。去掉 a[i] 后,还有 c1 - 1个与 a[i] 相同的元素,去掉 a[j] 后,还有 c2 - 1 个与 a[j] 相同的元素,它们还可以组成 (c1 - 1) * (c2 - 1) 个 x。
所以,如果分配给小hi的金币为 a[i]和a[j],那么存在 sumCnt - (c1 * c2 - (c1 - 1) * (c2 - 1)) 对 p, q 使得 a[i] + a[j] = a[p] + a[q]。
当 a[i] == a[j] 时,也是类似的处理。
现在,求p, q的组数只需要 O(1),总的时间复杂度是 O(n^2)。
如果不考虑非法组合的话, 辣么 对于 a[i] + a[j] = a[q] + a[p] = M。 假如 有x 对 a[i] + a[j] = M 的话,答案就是 C(m,2).
考虑重复。 举个栗子, 对于序列, 1 1 2 2 2。 当你M = 3,选择(1,3)(下标)时,你再选择其他(a[q],a[p])的情况,你要去掉 下标(1,4,)(1,5)(3,2)。 也就是 包含(1,3)中某一个的情况。可以发现有 (n+m-2)n为1个数,m为3个数。
1:v[
2;sumcnt[v[i]+v[j]]函数是存储sum=v[i]+v[j]的个数
1 #include
2 #include
3 #include
4 #include
5 #include <string>
6 #include
hihocoder 1505