【CodeForces553E】Kyoya and Train

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/84240624

【题目链接】

【思路要点】

  • 考虑一个暴力 dpdp ,记 dpi,jdp_{i,j} 表示在点 ii 处,时刻 jj 最优决策的期望花费。
  • 则有
    dpi,j={x+dist(i,N)j>T0i=N,jTMinieE{costi,e+k=1tpi,e,kdpe,j+k}iN,jTdp_{i,j}=\left\{\begin{array}{rcl}x+dist(i,N)&&{j>T}\\0&&{i=N,j≤T}\\Min_{i\Rightarrow e\in E}\{cost_{i,e}+\sum_{k=1}^{t}p_{i,e,k}*dp_{e,j+k}\}&&{i\ne N,j≤T}\end{array} \right.
  • 我们希望求出 dp1,0dp_{1,0}
  • 用分治 FFTFFT 优化该 dpdp 即可。
  • 具体来说,我们可以轻松地得到 dp,j (j>T)dp_{*,j}\ (j>T) ,也可以快速地计算出 dp,j (j>T)dp_{*,j}\ (j>T) 对后续 dpdp 的影响,即 transi,e,j=k=1t[j+k>T]pi,e,kdpe,j+ktrans_{i,e,j}=\sum_{k=1}^{t}[j+k>T]*p_{i,e,k}*dp_{e,j+k}
  • 那么考虑分治,对于时刻区间 [l,r][l,r] ,取 mid=l+r2mid=\lfloor\frac{l+r}{2}\rfloor ,首先计算出时刻区间 [mid+1,r][mid+1,r]dpdp 值,然后用 FFTFFT 计算时刻区间 [mid+1,r][mid+1,r]dpdp 值对时刻区间 [l,mid][l,mid] 的影响,即 transi,e,j=k=1t[mid<j+kr]pi,e,kdpe,j+ktrans_{i,e,j}=\sum_{k=1}^{t}[mid<j+k≤r]*p_{i,e,k}*dp_{e,j+k} ,最后递归计算时刻区间 [l,mid][l,mid]dpdp 值。
  • 时间复杂度 O(N3+MTLog2T)O(N^3+MTLog^2T)

【代码】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 55;
const int MAXM = 32768;
const double INF = 1e18;
const double pi = acos(-1);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
struct point {double x, y; };
point operator + (point a, point b) {return (point) {a.x + b.x, a.y + b.y}; }
point operator - (point a, point b) {return (point) {a.x - b.x, a.y - b.y}; }
point operator * (point a, point b) {return (point) {a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x}; }
point operator / (point a, double x) {return (point) {a.x / x, a.y / x}; }
int n, m, t, fine;
vector <pair <int, int> > e;
double dist[MAXN][MAXN], edge[MAXN][MAXN];
vector <double> dp[MAXN], trans[MAXN][MAXN], p[MAXN][MAXN];
int N, Log, home[MAXM]; point a[MAXM], b[MAXM], c[MAXM];
void FFT(point *a, int mode) {
	for (int i = 0; i < N; i++)
		if (home[i] > i) swap(a[i], a[home[i]]);
	for (int len = 2; len <= N; len <<= 1) {
		point delta = (point) {cos(2 * pi / len * mode), sin(2 * pi / len * mode)};
		for (int i = 0; i < N; i += len) {
			point now = (point) {1, 0};
			for (int j = i, k = i + len / 2; k < i + len; j++, k++) {
				point tmp = a[j], tnp = a[k];
				a[j] = tmp + tnp * now;
				a[k] = tmp - tnp * now;
				now = now * delta;
			}
		}
	}
	if (mode == -1) {
		for (int i = 0; i < N; i++)
			a[i] = a[i] / N;
	}
}
void transfer(int l, int mid, int r, vector <double> &dp, vector <double> &p, vector <double> &res) {
	N = 1, Log = 0;
	while (N <= (r - l) + (r - mid)) {
		N <<= 1;
		Log++;
	}
	for (int i = 0; i < N; i++) {
		int tmp = i, res = 0;
		for (int j = 1; j <= Log; j++) {
			res <<= 1;
			res += tmp & 1;
			tmp >>= 1;
		}
		home[i] = res;
	}
	for (int i = 0; i < N; i++)
		a[i] = b[i] = (point) {0, 0};
	for (int i = mid + 1; i <= r; i++)
		a[r - i].x = dp[i];
	for (int i = 0; i <= r - l; i++)
		b[i].x = p[i];
	FFT(a, 1), FFT(b, 1);
	for (int i = 0; i < N; i++)
		c[i] = a[i] * b[i];
	FFT(c, -1);
	for (int i = l; i <= mid; i++)
		res[i] += c[r - i].x;
}
void work(int l, int r) {
	if (l == r) {
		for (int i = 1; i <= n - 1; i++)
			dp[i][l] = INF;
		for (auto x : e) {
			int i = x.first, j = x.second;
			chkmin(dp[i][l], trans[i][j][l] + edge[i][j]);
		}
		return;
	}
	int mid = (l + r) / 2;
	work(mid + 1, r);
	for (auto x : e) {
		int i = x.first, j = x.second;
		transfer(l, mid, r, dp[j], p[i][j], trans[i][j]);
	}
	work(l, mid);
}
int main() {
	read(n), read(m), read(t), read(fine);
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
		if (i == j) dist[i][j] = 0;
		else dist[i][j] = INF;
	for (int i = 1; i <= n; i++)
		dp[i].resize(t + 1);
	for (int i = 1; i <= m; i++) {
		int x, y, z;
		read(x), read(y), read(z);
		e.emplace_back(x, y);
		dist[x][y] = z;
		edge[x][y] = z;
		p[x][y].push_back(0);
		trans[x][y].resize(t + 1);
		for (int j = 1; j <= t; j++) {
			int val; read(val);
			p[x][y].push_back(val * 0.00001);
		}
	}
	for (int k = 1; k <= n; k++)
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
		chkmin(dist[i][j], dist[i][k] + dist[k][j]);
	for (auto x : e) {
		int i = x.first, j = x.second;
		double res = 1;
		for (int k = t; k >= 0; k--) {
			res -= p[i][j][t - k];
			trans[i][j][k] = res * (dist[j][n] + fine);
		}
	}
	work(0, t);
	printf("%.10lf\n", dp[1][0]);
	return 0;
}
阅读更多

Train Time

11-17

DescriptionnnCity transportation planners are developing a light rail transit system to carry commuters between the suburbs and the downtown area. Part of their task includes scheduling trains on different routes between the outermost stations and the metro center hub. nnnPart of the planning process consists of a simple simulation of train travel. A simulation consists of a series of scenarios in which two trains, one starting at the metro center and one starting at the outermost station of the same route, travel toward each other along the route. The transportation planners want to find out where and when the two trains meet. You are to write a program to determine those results. nnnThis model of train travel is necessarily simplified. All scenarios are based on the following assumptions. nnAll trains spend a fixed amount of time at each station. nAll trains accelerate and decelerate at the same constant rate. All trains have the same maximum possible velocity. nWhen a train leaves a station, it accelerates (at a constant rate) until it reaches its maximum velocity. It remains at that maximum velocity until it begins to decelerate (at the same constant rate) as it approaches the next station. Trains leave stations with an initial velocity of zero (0.0) and they arrive at stations with terminal velocity zero. Adjacent stations on each route are far enough apart to allow a train to accelerate to its maximum velocity before beginning to decelerate. nBoth trains in each scenario make their initial departure at the same time. nThere are at most 30 stations along any route. nInputnnAll input values are real numbers. Data for each scenario are in the following format. nd1 d2 ... dn 0.0nFor a single route, the list of distances (in miles--there are 5,280 feet in a mile) from each station to the metro center hub,separated by one or more spaces. Stations are listed in ascending order, starting with the station closest to the metro center hub (station 1) and continuing to the outermost station. All distances are greater than zero. The list is terminated by the sentinel value 0.0.nvnThe maximum train velocity, in feet/minute.nsnThe constant train acceleration rate in feet/minute².nmnThe number of minutes a train stays in a station.nnThe series of runs is terminated by a data set which begins with the number -1.0.nOutputnnFor each scenario, output consists of the following labeled data. nnnThe number of the scenario (numbered consecutively, starting with Scenario #1). nThe time when the two trains meet in terms of minutes from starting time. All times must be displayed to one decimal place. nThe distance in miles between the metro center hub and the place where the two trains meet. Distances must be displayed to three decimal places. Also, if the trains meet in a station, output the number of the station where they meet. nPrint a blank line after each scenario.nSample Inputnn15.0 0.0n5280.0n10560.0n5.0n3.5 7.0 0.0n5280.0n10560.0n2.0n3.4 7.0 0.0n5280.0n10560.0n2.0n-1.0nSample OutputnnScenario #1n Meeting time: 7.8 minutesn Meeting distance: 7.500 miles from metro center hubnnScenario #2n Meeting time: 4.0 minutesn Meeting distance: 3.500 miles from metro center hub, in station 1nnScenario #3n Meeting time: 4.1 minutesn Meeting distance: 3.400 miles from metro center hub, in station 1

Train Scheduling

02-05

Elihc is a strange country occupying a long, narrow strip of land from north to south. There is only one main railway line in this country. This railway line is a straight line. It starts from the northernmost station, traverses the whole country southward, and finishes at the southernmost station. nnUnfortunately, there are too many trains travelling on this railway line all the time. Long delays, even serious railway accidents are quite common here. Now, Railways Bureau of Elihc decides to solve these problems by scheduling the train in a better way, and hires you to write the program. nnThere are (N+1) stations on this railway line, and they are numbered from 0 to N from north to south. There are also M trains numbered from 0 to M-1. Each train has an initial station, a terminal station, expected time of departure and speed limit. Initially, it parks at its initial station. It departs at the expected time or after the expected time, and is bound for its terminal station. The train has to stop at every station on its route. Different trains may have different speed limits. During the journey, a train should always run within its own speed limit (it is allowed to run at any speed not exceeding the limit anywhere). Compared with the railway line, both stations and trains are so small that they can be regarded as points in your scheduling program. nnFor each pair of adjacent stations, the part of the railway line between them is called a section (stations are not included). The positions of the stations are well designed so that the length of each section is exactly S kilometer. All stations are sufficient to park any number of trains. However, due to some financial difficulties, there is just one track for each section. For safety reasons, trains running on the same section should always follow the rules below. nn1. They are running in the same direction. n2. A train can catch up with, but can never pass any other trains in front of it. nnAn officer of Railways Bureau provides you some scheduling strategies, which you have to use in your program: nn1. During scheduling, trains that are not expected to depart yet should be ignored. If a train has already arrived at its terminal station, it will be ignored forever. n2. Once a train is expected to depart from the original station, or arrives at a station except the terminal one, it stops and waits to move on the next section immediately. n3. When a train is stopping in some station, it will not start to move to the next section until (1) no running train is coming from the opposite direction on this section, and (2) No train with smaller number is stopping and waiting to move on this section from station at either end of this section. n4. A train should always run as fast as it can, without passing any train in front running on the same section. nnNow, please help Railways Bureau to schedule the trains and figure out when each train will reach its terminal station. n输入描述:nnThere are several test cases in the input.n nn The first line contains an integer C (1 ≤ C ≤ 10) -- the number of test cases.n nn Each test case begins with three integers N, M, S (1 ≤ N ≤ 10, 1 ≤ M ≤ 10, 1 ≤ S ≤ 1000), indicating the number of stations, the number of trains and the length of section (in kilometer).n nn Then M lines follow, describing trains from number 0 to M-1 in order, one per line. Each line contains four integers O, T, E, L (0 ≤ O ≤ N, 0 ≤ T ≤ N, O ≠ T, 0 ≤ E ≤ 10000, 1 ≤ L ≤ S), indicate that this train travels from station O to station T, expected to depart at minute E, and its speed limit is L kilometer per minute.nnn输出描述:nnFor each test case, output the arrival time (in minute) of each train one per line, in ascending order of train number. Your answers should be rounded up to the nearest integer.nn输入例子:nn2n1 3 100n0 1 0 5n0 1 20 5n1 0 0 5n2 2 100n0 2 0 4n0 2 2 5nn输出例子:nn20n40n60n50n50

没有更多推荐了,返回首页