暴力枚举+idea。做的时候mod写错了,写成了1000000009,找了两个多小时才发现......
a[1],a[2],a[3]....a[N]
b[1],b[2],b[3]....b[N]
首先需要枚举b[1]...b[N]与a[1]进行组合。
然后对a[2]...a[N]从小到大排序
对b[1],b[2],b[3]....b[N] 除当前与a[1]组合的以外,剩下的从大到小排序
然后找出每一个a[i]在不破坏a[0]最大值的情况下最大能与哪一个b[i]配对。
然后从第N个人开始往第2个人开始计算,先算N有几种取法,然后算N-1有几种。。。一直算到第2个人有几种
然后把这些数字乘起来就是当前这一次枚举的答案,最后把所有答案加起来就是了
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int maxn = 100 + 10; const long long MOD = 1000000007; long long tmpa[maxn]; long long tmpb[maxn]; long long a[maxn]; long long b[maxn]; long long flag[maxn]; int n; bool cmp(const long long&a, const long long&b) { return a>b; } int main() { while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) scanf("%lld", &tmpa[i]); for (int i = 1; i <= n; i++) scanf("%lld", &tmpb[i]); long long ans = 0; for (int t = 1; t <= n; t++) { long long top = tmpa[1] * tmpb[t]; for (int i = 1; i <= n - 1; i++) a[i] = tmpa[i + 1]; int u = 1; for (int i = 1; i <= n; i++) { if (i == t) continue; else b[u++] = tmpb[i]; } int tot = n - 1; sort(a + 1, a + 1 + tot); sort(b + 1, b + 1 + tot, cmp); for (int i = 1; i <= n; i++) flag[i] = (long long)1000; for (int i = 1; i <= tot; i++) { for (int j = 1; j <= tot; j++) { if (a[i] * b[j] >= top){} else { flag[i] = (long long)j; break; } } } long long ans_tmp = 1; bool fail = 0; for (int i = 1; i <= tot; i++) if (flag[i] > (long long)i) { ans_tmp = 0; fail = 1; break; } if (fail == 0) { long long now = 0; long long newpos = (long long)(tot + 1); for (int i = tot; i >= 1; i--) { long long newz = 0; if (flag[i] < newpos) { newz = newpos-flag[i]; newpos = flag[i]; } now = now + newz; ans_tmp = (ans_tmp*now) % MOD; now--; } } ans = (ans + ans_tmp) % MOD; } printf("%lld\n", ans); } return 0; }
CDOJ 1273 God Qing's circuital law
时间: 2024-10-25 13:40:51