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++ (judge verdict: Accepted)

#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

enum Type{
	Current,
	Next,
};

struct Info{
	Info(){
		x = y = 0;
	}
	double x,y;
};


double calc_dist(Info left,Info right){
	return sqrt((left.x-right.x)*(left.x-right.x)+(left.y-right.y)*(left.y-right.y));
}

double calc_naiseki(Info left,Info right){
	return left.x*right.x+left.y*right.y;
}

int main(){

	int N;
	double Limit,Angle;
	scanf("%d",&N);
	scanf("%lf %lf",&Limit,&Angle);

	Info info[N];

	double dp[N][N][2],dist[N][N];
	bool check[N][N][N];

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++){
			for(int p = 0; p < N; p++)check[i][k][p] = false;
		}
	}

	for(int i = 0; i < N; i++){
		scanf("%lf %lf",&info[i].x,&info[i].y);
	}

	double tmp;
	for(int i = 0; i < N-1; i++){
		for(int k = i+1; k < N;k++){
			tmp = calc_dist(info[i],info[k]);
			dist[i][k] = tmp;
			dist[k][i] = tmp;
		}
	}

	Info vector_1,vector_2;
	double len_1,len_2,naiseki,cos_value,kakudo;

	for(int start = 0; start < N; start++){
		for(int mid = 0; mid < N; mid++){
			if(start == mid)continue;
			for(int goal = 0; goal < N; goal++){
				if(start != goal && mid != goal){

					len_1 = calc_dist(info[goal],info[mid]);
					len_2 = calc_dist(info[mid],info[start]);

					vector_1.x = info[goal].x - info[mid].x;
					vector_1.y = info[goal].y - info[mid].y;

					vector_2.x = info[mid].x - info[start].x;
					vector_2.y = info[mid].y - info[start].y;

					naiseki = calc_naiseki(vector_1,vector_2);

					cos_value = naiseki/(len_1*len_2);

					kakudo = acos(cos_value)*180.0/M_PI;

					if(kakudo <= Angle){
						check[start][mid][goal] = true;
					}
				}
			}
		}
	}

	int maximum = 0;
	bool FLG = false;;

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++)dp[i][k][Current] = DBL_MAX;
	}

	for(int first = 1; first < N; first++){
		if(dist[0][first] <= Limit){
			dp[first][0][Current] = dist[0][first];
			FLG = true;
		}
	}

	if(FLG)maximum++;

	while(true){

		FLG = false;

		for(int i = 0; i < N; i++){
			for(int k = 0; k < N; k++)dp[i][k][Next] = DBL_MAX;
		}

		for(int start = 0; start < N; start++){
			for(int pre = 0; pre < N; pre++){
				if(dp[start][pre][Current] == DBL_MAX)continue;
				for(int to = 0; to < N; to++){
					if(start != to && pre != to){
						if(check[pre][start][to] == true && dp[to][start][Next] > dp[start][pre][Current]+dist[start][to] && dp[start][pre][Current]+dist[start][to] <= Limit){
							dp[to][start][Next] = dp[start][pre][Current]+dist[start][to];
							FLG = true;
						}
					}
				}
			}
		}


		if(!FLG)break;
		else{
			for(int i = 0; i < N; i++){
				for(int k = 0; k < N; k++)dp[i][k][Current] = dp[i][k][Next];
			}
			maximum++;
		}
	}


	printf("%d\n",maximum);

	return 0;
}