AcWing 1075. 숫자 변환 (트 리 DP) 문제 풀이
만약 에 하나의 x 의 약수 와 y (그 자 체 를 포함 하지 않 음) 가 그 자체 보다 작다 면 x 는 y 가 될 수 있 고 y 도 x 가 될 수 있다.
예 를 들 어 4 는 3, 1 은 7 로 변 할 수 있다.
모든 디지털 변환 을 n 을 초과 하지 않 는 정수 범위 내 에서 한정 하고 디지털 변환 을 계속 진행 하 며 중복 숫자의 최대 변환 단계 가 나타 나 지 않도록 한다.
입력 형식
정수 n 을 입력 하 십시오.
출력 형식
출력 은 끊임없이 디지털 변환 을 진행 하고 중복 숫자의 최대 변환 단계 가 나타 나 지 않 습 니 다.
데이터 범위
1≤n≤50000
입력 예시:
7
출력 예시:
3
예 를 들 어 해석 하 다.
한 가지 방안 은 4 → 3 → 1 → 7 이다.
문제 풀이:
트 리 DP:
먼저 각 수의 약수 의 합 을 미리 처리 하면 우 리 는 모든 합 법 적 인 경 로 를 건설 할 수 있다.
마지막 으로 나 무 를 구 하 는 가장 긴 경로 문제 로 바 뀔 수 있다.
#include
#include
using namespace std;
const int N = 50010;
int n;
int h[N], e[N], ne[N], idx;
int sum[N];
bool vis[N];
int ans;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int dfs(int u) // u
{
int d1 = 0, d2 = 0; //
for(int i = h[u]; i != -1; i = ne[i]){
int j = e[i];
int d = dfs(j) + 1;
if(d >= d1){
d2 = d1;
d1 = d;
}
else if(d >= d2)d2 = d;
}
ans = max(ans, d1 + d2);
return d1;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) //
for(int j = 2; j <= n / i; j++)
sum[i * j] += i;
memset(h, -1, sizeof h); //1 0, 2
for(int i = 2; i <= n; i++){
if(i > sum[i]){
//
add(sum[i], i);
vis[i] = true; //
}
}
for(int i = 1; i <= n; i++){
if(!vis[i]){
//
dfs(i);
}
}
cout << ans << endl;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
124. 두 갈래 나무의 최대 경로와 leetcode비공 두 갈래 트리를 지정하고 최대 경로와 를 되돌려줍니다. 본고에서 경로는 나무의 임의의 노드에서 출발하여 임의의 노드에 도달하는 서열로 정의되었다.이 경로는 루트 노드를 거치지 않고 하나 이상의 노드를 포함합니다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.