---
# System prepended metadata

title: 'c039-acm: The 3n + 1 problem'
tags: [蘿莉控自學]

---

---
tags: 蘿莉控自學
---
> 蘿莉控的C++自學筆記
# c039-acm: The 3n + 1 problem
連結: https://zerojudge.tw/ShowProblem?problemid=c039
## Sol1. 假解
用DP和遞迴天真
可以AC(測資不夠強)
N開大一點就過了，如果開1000005會RE(記憶體區段錯誤)，因為會讀到範圍外的數字
AC(3ms, 5MB)
```cpp=
#include<bits/stdc++.h>
using namespace std;
const int N = 100000005;
int dp[N] = {0};
int solve(int x){
    if (x == 1) return 1;
    if (dp[x] != 0) return dp[x];
    int len;
    if (x % 2 == 1){
        len = solve(3*x+1) + 1;
    }else len = solve(x / 2) + 1;
    dp[x] = len;
    return dp[x];
}
int main(){
    int i, j;
    while (cin >> i >> j){
        bool note = false;
        if (i > j){
            swap(i, j);
            note = true;
        }
        int max_len = 0;
        for(int k = i;k <= j;k ++){
            max_len = max(max_len, solve(k));
        }
        if (!note) cout << i <<" "<< j <<" "<< max_len << endl;
        else cout << j <<" "<< i <<" "<< max_len << endl;
    }
}

```
# Sol2.
就是和前面一樣
但在超過1000005的範圍時不查表
這應該很容易就不寫了~~
(好啦還是寫一下)
AC(3ms, 4.2MB)
```cpp=
#include<bits/stdc++.h>
using namespace std;
const int N = 1000005;
int dp[N] = {0};
int solve(int x){
    if (x == 1) return 1;
    if (!(x > 1000000))if (dp[x] != 0) return dp[x];
    int len;
    if (x % 2 == 1){
        len = solve(3*x+1) + 1;
    }else len = solve(x / 2) + 1;
    if (!(x > 1000000))dp[x] = len;
    if (!(x > 1000000))return dp[x];
    else return len;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int i, j;
    while (cin >> i >> j){
        bool note = false;
        if (i > j){
            swap(i, j);
            note = true;
        }
        int max_len = 0;
        for(int k = i;k <= j;k ++){
            max_len = max(max_len, solve(k));
        }
        if (!note) cout << i <<" "<< j <<" "<< max_len << endl;
        else cout << j <<" "<< i <<" "<< max_len << endl;
    }
}

```
> 回到主頁: https://hackmd.io/C_fY69EtSXeHHPLT1QxUug

