Problem:
Problem B: Carrot Tour

うさぎがある国を旅行している. この国には1 からn の番号がついたn 個の都市があり, うさぎは今都市1にいる. 都市i は座標平面上の1 点(xi, yi) とみなす.

うさぎは以下の条件をみたすように旅をする.

移動経路は折れ線であり, その各部分は異なる2 都市を結ぶ線分でなければならない.

移動経路の全長はr 以下でなければならない. 経路のうち重なった部分も, 通った回数分数える.

移動する方向が変わるとき, 曲がる角度はθ 以下でなければならない. 最初の移動方向に制限はない.

うさぎがある都市から別の都市へ移動をすると, 移動先の都市でニンジンを1 本もらえる. 同じ都市を複数回訪れることは可能であり, 訪れるたびにニンジンをもらえる. うさぎがこの旅で手に入れることのできるニンジンの本数の最大値を求めよ.

Input

入力の一行目には一つの整数n が, 二行目には二つの実数r, θ がスペースで区切られて与えられる.

1 ≤ n ≤ 20

0 < r < 104

0° < θ < 180°

続くn 行には, 整数xi, yi がスペースで区切られて与えられる

-10 000 ≤ xi, yi ≤ 10 000

r, θ を±10−3 以内で変化させても答えは変わらない.

どの2 つの都市の位置も異なる.

Output

うさぎがこの旅で手に入れることのできるニンジンの本数の最大値を一行に出力せよ.

Sample Input 1

5
100.1 90.1
0 0
0 10
5 5
10 0
10 10

Sample Output 1

10

Solution in C++14 (judge verdict: Accepted)

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <complex>

using Real = long double;
using Point = std::complex<Real>;
using Segment = std::pair<Point, Point>;

const Real PI = acos(-1);
const Real EPS = 1e-10;

std::istream& operator>>(std::istream& is, Point& p) {
    Real x, y;
    is >> x >> y;
    p = Point(x, y);
    return is;
}

inline int compare(Real a, Real b) {
    if (std::abs(a - b) < EPS) return 0;
    return a - b > 0 ? 1 : -1;
}

inline Real dist(Point a, Point b) {
    return std::abs(a - b);
}

inline Real dot(Point x, Point y) {
    return std::real(std::conj(x) * (y));
}


using namespace std;

int main() {
    int N;
    Real r, theta;
    cin >> N >> r >> theta;
    theta *= PI / 180;

    vector<Point> ps(N);
    for (auto& p : ps) cin >> p;

    vector<vector<Real>> d(N * N, vector<Real>(N * N, 1e50));
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            if (i == j) continue;
            for (int k = 0; k < N; ++k) {
                if (j == k) continue;

                Real costheta = dot(ps[j] - ps[i], ps[k] - ps[j]) / (dist(ps[j], ps[i]) * dist(ps[k], ps[j]));
                if (costheta < -1) costheta += EPS;
                if (costheta > 1) costheta -= EPS;
                if (compare(acos(costheta), theta) > 0) continue;

                d[i * N + j][j * N + k] = dist(ps[j], ps[k]);
            }
        }
    }

    vector<vector<Real>> dp(N * N, vector<Real>(10001, 1e100));
    // dp[i][j][n] = 直前i、今jにいて、既にk箇所訪れたときの最短距離

    for (int i = 1; i < N; ++i) {
        dp[i][1] = dist(ps[0], ps[i]);
    }

    for (int n = 1; n < 10000; ++n) {
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                if (i == j) continue;
                for (int k = 0; k < N; ++k) {
                    if (j == k) continue;

                    dp[j * N + k][n + 1] = min(dp[j * N + k][n + 1], dp[i * N + j][n] + d[i * N + j][j * N + k]);
                }
            }
        }
    }

    int ans = 0;
    for (int v = 0; v < N * N; ++v) {
        for (int n = 0; n <= 10000; ++n) {
            if (compare(dp[v][n], r) <= 0) ans = max(ans, n);
        }
    }

    cout << ans << endl;
    return 0;
}