比赛的时候想错方向了:disappointed:
Solution #
设从里向外多边形的边数为。不难发现必须是的倍 数,因此我们可以把写成。所以 如果我们知道最里面的多边形的边数,那么剩下的事情就是找到最长的序列 使得是的倍数并且。
注意都是的倍数,所以如果我们把它们都除以就又得到 了一个以开头的序列!也就是说我们得到了一个更小的子问题,所以我们可以用动态规 划来解决:设为和为的上述序列的最大长度。因为我们可以把一个短的序列乘上 一个数并在最前面放一个,从而得到一个更长的序列,所以状态转移就是:
代码 #
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tt = 1;
cin >> tt;
constexpr int N = 1e6;
vector<int> dp(N + 1, 1);
for (int i = 1; i <= N; i++) {
for (int j = 2 * i + 1; j <= N; j += i) {
dp[j] = max(dp[j], dp[i] + 1);
}
}
for (int cas = 1; cas <= tt; cas++) {
int x;
cin >> x;
int ans = 1;
cout << "Case #" << cas << ": ";
for (int f = 3; f <= x; f++) {
if (x % f == 0) ans = max(ans, dp[x / f]);
}
cout << ans << '\n';
}
return 0;
}