【每日一题】26.codeJan与旅行 (贪心)

补题链接:Here

算法涉及:贪心

思路:

首先,我们处在p位置,显然要么向左走到相邻的城市,要么向右走走到相邻的城市。
有一个不会证明但观察到的结论,从这两个位置走的话,只有四种可能。
可能1:一直向左走
可能2:一直向右走
可能3:一直向左走到第i个城市,然后再向右走到第i+1个城市,然后再向左走到第i个城市,然后再向右走到第i+1个城市...
可能4:一直向右走到第i个城市,然后再向左走到第i-1个城市,然后再向右走到第i个城市,然后再向左走到第i-1个城市...

贴一个证明过程:Here

using ll = long long;
const int N = 1e5 + 6, M = 1e5;// val 1e9
void solve() {
	int n, m, p, pos = 0;
	cin >> n >> m >> p;
	ll a[n + 1];
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
		if (a[i] < p)pos = i;
	}
	ll ans = 1e18;
	for (int i = 1; i < n; ++i) {
		if (i <= pos) {
			if (pos - i  + 1 > m)continue;
			ll num = m - (pos - i + 1), dist = p - a[i];
			ans = min(ans, dist + num * (a[i + 1] - a[i]));
			if (num > 0 and pos + 1 <= n)
				ans = min(ans, (a[pos + 1] - p) * 2 + dist + (num - 1) *
				          (a[i + 1] - a[i]));
		} else {
			if (i - pos > m)continue;
			ll num = m - (i - pos), dist = a[i] - p;
			ans = min(ans, dist + num * (a[i + 1] - a[i]));
			if (num > 0 and pos >= 1)
				ans = min(ans, (p - a[pos]) * 2 + dist + (num - 1) *
				          (a[i + 1] - a[i]));
		}
	}
	cout << ans << endl;
}
posted @ 2021-05-15 10:19  RioTian  阅读(70)  评论(0编辑  收藏  举报