public class RuangVsWaktu {

    public static void main(String[] args) {
        int n = 30;
        long hasilA = fibDuaVariabel(n);
        long hasilB = fibTabel(n);

        System.out.println("Fibonacci ke-" + n + " = " + hasilA);
        System.out.println("Versi dua variabel : 2 slot long, waktu O(n)");
        System.out.println("Versi tabel dp     : " + (n + 1) + " slot long, waktu O(n)");
        System.out.println("Hasil kedua versi sama: " + (hasilA == hasilB));
    }

    // Versi hemat ruang: hanya menyimpan dua nilai terakhir.
    static long fibDuaVariabel(int n) {
        long a = 0; // fib(0)
        long b = 1; // fib(1)
        for (int i = 1; i <= n; i++) {
            long berikutnya = a + b;
            a = b;
            b = berikutnya;
        }
        return a;
    }

    // Versi boros ruang: menyimpan seluruh tabel hasil antara.
    static long fibTabel(int n) {
        long[] dp = new long[n + 1];
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}
