题解:P10282 [USACO24OPEN] Smaller Averages G
Christmas_Defunct · · 题解
去年 USACO 的题目,比赛时没做出来,今天上课老师正好讲到了,才补出来。如此补题,怎能不爱?
先看数据,对于
然后是
此时有一个
的时候,
但是此时做法的复杂度完全无法接受,
所以现在重点在于考虑如何优化。
我们可以尝试优化
如果细品一下其实感觉挺有道理的,用
对
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 505, mod = 1e9 + 7;
int n, a[maxn], b[maxn];
struct node {
int id;
long double avg;
friend bool operator < (node x, node y) {
if (x.avg != y.avg) return x.avg < y.avg;
return x.id < y.id;
}
} s1[maxn][maxn], s2[maxn][maxn];
int s[maxn][maxn], f[maxn][maxn];
signed main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] += a[i - 1];
for (int j = 0; j < i; j++) {
s1[i][j + 1] = (node){j, double(a[i] - a[j]) / (i - j)};
}
sort(s1[i] + 1, s1[i] + i + 1);
}
for (int i = 1; i <= n; i++) {
cin >> b[i];
b[i] += b[i - 1];
for (int j = 0; j < i; j++) {
s2[i][j + 1] = (node){j, double(b[i] - b[j]) / (i - j)};
}
sort(s2[i] + 1, s2[i] + i + 1);
}
f[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n; j++) {
for (int k = 1; k <= i; k++) {
s[j][k] = s[j][k - 1] + f[s1[i][k].id][j];
s[j][k] %= mod;
}
}
for (int j = 1; j <= n; j++) {
for (int k = 1, l = 1; l <= j; l++) {
while (k <= i && s1[i][k].avg <= s2[j][l].avg) k++;
f[i][j] += s[s2[j][l].id][k - 1];
f[i][j] %= mod;
}
}
}
cout << f[n][n] << '\n';
return 0;
}