AcWing 1075 數字轉換

2021-10-03 00:06:40 字數 1182 閱讀 9232

題目描述:

如果乙個數 x 的約數之和 y(不包括他本身)比他本身小,那麼 x 可以變成 y,y 也可以變成 x。

例如,4 可以變為 3,1可以變為 7。

限定所有數字變換在不超過 n 的正整數範圍內進行,求不斷進行數字變換且不出現重複數字的最多變換步數。

輸入格式

輸入乙個正整數 n。

輸出格式

輸出不斷進行數字變換且不出現重複數字的最多變換步數。

資料範圍

1≤n≤50000

輸入樣例:

7
輸出樣例:

3
樣例解釋

一種方案為:4→3→1→7。

分析:首先,乙個數字可以變成另外乙個數字,就算是這兩個數字之間存在一條邊,當x的約數之和y小於x時,x與y之間邊存在邊。乙個數的約數之和是唯一的,但乙個數可以是很多數的約數之和,所以乙個數的父節點就是這個數的約數之和。首先考慮如何求出1-n中所有數的約數之和,由於要在不超過n的正整數範圍內變換,所以不需要求1的約數之和。可以採用類似於篩法的形式去求約數之和,將i的若干倍都加到其倍數的約數之和上即可。

for(int i = 1;i <= n / 2;i++)

}

然後仿照樹的最長路徑那題對樹做dfs,求出最長路徑就是本題的最多變換步數了,因為不能確定1到n中所有的數都是連通的,所以需要多次進行dfs來遍歷這個森林。這裡的邊也可以設定為雙向的,但是由於是從小到大進行dfs,相當於從根節點開始遍歷,就不需要增加孩子節點指向父節點的邊來降低dfs的速度了。

#include #include #include using namespace std;

const int n = 50005;

int s[n],h[n],e[n],ne[n],idx,ans;

bool vis[n];

void add(int a,int b)

int dfs(int u)

ans = max(ans,d1 + d2);

return d1;

}int main()

}for(int i = 2;i <= n;i++)

for(int i = 1;i <= n;i++)

cout

}

ACWing 1075 數字轉換

如果乙個數x xx的約數之和y yy 不包括他本身 比他本身小,那麼x xx可以變成y yy,y yy也可以變成x xx。例如,4 44可以變為3 33,1 11可以變為7 77。限定所有數字變換在不超過n nn的正整數範圍內進行,求不斷進行數字變換且不出現重複數字的最多變換步數。輸入格式 輸入乙個...

acwing 1075 數字轉換 (樹形DP)

首先,對於小於n的每個數,我們可以確定它的約數之和 不包括自己 是固定的,就像4的約數之和一定是3,不可能是其他的,那麼我們就可以將2 n的每個數的約數之和求出sum i 對於sum i i 的邊 因為對於每個i,sum i 是唯一確定的 也就是說每個兒子都有唯一乙個父節點,那麼我們最終就會構成森林...

AcWing1075 數字轉換 樹形DP 題解

題目傳送門 如果乙個數 x 的約數之和 y 不包括他本身 比他本身小,那麼 x 可以變成 y,y 也可以變成 x。例如,4 可以變為 3,1 可以變為 7。限定所有數字變換在不超過 n 的正整數範圍內進行,求不斷進行數字變換且不出現重複數字的最多變換步數。輸入格式 輸入乙個正整數 n。輸出格式 輸出...