# Dynamic Programming# Greedy# Optimization

b595 - Special Touring Car Racing

🔗 前往 ZeroJudge 原題

題目描述

題目描述了一場特殊的房車賽,參賽者需要在若干個停車區域中選擇停靠點,最終到達終點。目標是最小化每日行駛距離與理想距離 200 之間的差的平方和,以此最小化總罰金。

解題思路

本題可以使用動態規劃來解決。dp[i] 表示到達第 i 個停車區域所需的最小罰金。對於每個停車區域 i,我們遍歷之前的停車區域 j,計算從 ji 的行駛距離 x,並計算對應的罰金 (200 - x)^2dp[i] 的值是所有可能的 j 中,dp[j] + (200 - x)^2 的最小值。gt[i] 記錄了到達 i 最小罰金的前一個停車區域,用於回溯最佳路徑。最後,從終點開始回溯,重建最佳路徑並輸出。

複雜度分析

  • 時間複雜度: O(n^2),其中 n 是停車區域的數量。因為需要遍歷所有可能的停車區域組合。
  • 空間複雜度: O(n),用於儲存 dpgtans 陣列。

程式碼

#include<bits/stdc++.h>
using namespace std;
long long n,a[10005],dp[10005],gt[10005],ans[10005];
int main(){
    cin.tie(0); ios::sync_with_stdio(0);
    while(cin >> n){
    	if(n==0)break;
    	memset(dp,0x3f,sizeof(dp));
    	dp[0]=0;
		for(int i=1;i<=n;++i){
    		cin >> a[i];
			for(int j=0;j<i;++j){
				if(dp[j]+(200-a[i]+a[j])*(200-a[i]+a[j])<dp[i]){
					dp[i]=dp[j]+(200-a[i]+a[j])*(200-a[i]+a[j]);
					gt[i]=j;
				}
			}
		}
		int sz=0,it=n;
		while(it){
			ans[sz++]=it;
			it=gt[it];
		}
		cout << "0 ";
		for(int i=sz-1;i>=0;--i){
			cout << ans[i] << " ";
		}
		cout << "\n";
	}
}

Discussion