1967:Alibaba
問題文
http://poj.org/problem?id=1967
宝の位置とその宝を取れる制限時間が与えられる。任意の位置からスタートして、宝を全て拾うときの最短時間を求めよ。
区間DP。
l[訪れた区間の左端][右端]:=訪れた区間の左端を終端とする最短時間
r[訪れた区間の左端][右端]:=訪れた区間の右端を終端とする最短時間
#include<iostream> #include<vector> #include<cmath> #include<algorithm> #define INF (1<<29) using namespace std; int main(void){ int n; while(cin >> n){ int pos[10001],time[10001]; for(int i=0;i<n;i++)cin >> pos[i] >> time[i]; int l[10001],r[10001],pl[10001],pr[10001]; for(int i=n-2;i>=0;i--){ fill(l,l+n,INF); fill(r,r+n,INF); l[i]=r[i]=0; for(int j=i+1;j<n;j++){ if(pl[j]+abs(pos[i]-pos[i+1])<time[i]) l[j]=min(l[j],pl[j]+abs(pos[i]-pos[i+1])); if(pr[j]+abs(pos[i]-pos[j])<time[i]) l[j]=min(l[j],pr[j]+abs(pos[i]-pos[j])); if(l[j-1]+abs(pos[i]-pos[j])<time[j]) r[j]=min(r[j],l[j-1]+abs(pos[i]-pos[j])); if(r[j-1]+abs(pos[j-1]-pos[j])<time[j]) r[j]=min(r[j],r[j-1]+abs(pos[j-1]-pos[j])); } copy(l,l+n,pl); copy(r,r+n,pr); } int ans=min(l[n-1],r[n-1]); if(ans>=INF)cout << "No solution" << endl; else cout << ans << endl; } return 0; }