# Dynamic Programming# Greedy# Optimization

b672 - A Special Automobile Race

🔗 前往 ZeroJudge 原題

題目描述

題目描述一個特殊的汽車競賽,競賽的目標不是速度,而是數學能力。賽道上有 n 個休息站,每個休息站的汽車可以行駛不同的距離。玩家必須在每個休息站更換汽車。目標是找到到達終點所需的最小休息站數量。起始點的汽車至少可以行駛到下一個 5 個休息站。

解題思路

這題可以使用動態規劃來解決。dp[i] 表示到達第 i 個休息站所需的最小休息站數量。初始化 dp[0] = 0。對於每個休息站 i,我們遍歷它可以到達的所有休息站 j(從 i+1 到 min(a+i, n)),如果 dp[j] 尚未被更新,則更新 dp[j] = dp[i] + 1。如果 dp[j] 已經被更新,則取 dp[j]dp[i] + 1 的最小值。由於題目要求最小的休息站數量,且起始點可以到達下一個 5 個休息站,因此可以視為一個貪心策略的動態規劃問題。

複雜度分析

  • 時間複雜度: O(n^2)
  • 空間複雜度: O(n)

程式碼

#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
inline int read(){
	int a(0);
	char c('0');
	while(c>='0'){
		a=(a<<3)+(a<<1)+c-'0';
		c=getchar_unlocked();
	}
	return a;
}
using namespace std;
int main(){
	cin.tie(0); ios::sync_with_stdio(false);
	int n,a;
	while(n=read()){
		if(!n)break;
		int dp[n+1]={0};
		for(int i=0;i<n;++i){
			a=read();
			for(int j=i+1,k=dp[i]+1,z=min(a+i,n);j<=z;++j)
				if(j>4)
					(!dp[j])?dp[j]=k:dp[j]=min(k,dp[j]);
		}
		cout << dp[n] << "\n";
	}
}

Discussion