# GCD(UVA11417) ## [程式繳交區](https://hackmd.io/@Renektonn/S18g8y6uke/edit) ## 題目 [點我](https://onlinejudge.org/external/114/11417.pdf) ## 解題網站 [UVA](https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2412) [ZJ](https://zerojudge.tw/ShowProblem?problemid=d255) ## 演算法 ``` 1. 輸入n,若為0,則停止 2. G=0; for(i=1;i<N;i++) { for(j=i+1;j<=N;j++) { G+=GCD(i,j); } } 3. 輸出G ``` ## 程式碼 ```cpp= #include <bits/stdc++.h> using namespace std; int gcd (int a, int b) { if (b == 0) return a; return gcd(b, a % b); } int main() { int n; while (cin >> n) { if (n == 0) break; int g = 0; for (int i = 1; i < n; i++) { for (int j = i + 1; j <= n; j++) { g += gcd(i, j); } } cout << g << endl; } return 0; } ``` ## 時間複雜度 $O(tn^2\log(n))$ $n=500, t=100$ $100\times250000\times 9=2.25\times10^8$ 我覺得勉強能過 ## 更好的演算法 使用動態規劃 ``` 1. 定義子問題:g(i)代表當n為i,G的值 2. 遞迴關係式: g(n) = 1, n = 2 g(n) = g(n - 1) + gcd(j, i), j = [1, i - 1] 3. 計算順序:bottom-up,由小到大即可 4. 答案在g[n] ``` ``` 1. 使用動態規劃建表 2. 輸入n,若為0,則停止 3. 輸出g(n) ``` ## 程式碼 ```cpp= #include <bits/stdc++.h> using namespace std; int gcd (int a, int b) { if (b == 0) return a; return gcd(b, a % b); } int main() { int g[501] = {}; g[2] = 1; for (int i = 3; i <= 500; i++) { int sum = g[i - 1]; for (int j = 1; j < i; j++) { sum += gcd(j, i); } g[i] = sum; } int n; while (cin >> n) { if (n == 0) break; cout << g[n] << endl; } return 0; } ``` ## 時間複雜度 $O(max(n^2, t))$ $n=500, t=100$ 計算量為$250000=2.5\times10^5$