500pts:
枚举哪些列相同,然后做一个
dp
d
p
。
cost[i][j]
c
o
s
t
[
i
]
[
j
]
表示对称的i行,有
j
j
个回文串。只可能时
0,1,2,
0
,
1
,
2
,
这里贪心一下即可。然后做一个背包
dp
d
p
。
代码暂时找不到了。
900pts:
考虑交点个数,对于两条直线
y=ax+b
y
=
a
x
+
b
y=cx+d
y
=
c
x
+
d
(c<a)
(
c
<
a
)
那么
x=a−cd−b
x
=
a
−
c
d
−
b
考虑本质不同的
x
x
个数,那么相当于求多少个不同的与
d−b
d
−
b
互质。
a−c
a
−
c
的范围是
[1,a]
[
1
,
a
]
,
d−b
d
−
b
的范围是
[−b,B−d]
[
−
b
,
B
−
d
]
那么预处理互质的数的个数,然后暴力计算即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 1505;
long long dp[maxn][maxn];
int gcd(int a, int b) {
return !b ? a : gcd(b, a % b);
}
class LotsOfLines {
public:
long long countDivisions(int A, int B) {
for(int i = 1; i <= A; ++i) {
for(int j = 1; j <= B; ++j) {
dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1] + (gcd(i, j) == 1);
}
}
long long ans = B + 1;
for(int i = 1; i < A; ++i) {
for(int j = 0; j < B; ++j) {
ans += 2 + dp[i][j] + dp[i][B - j - 1];
}
}
return ans;
}
};