UVA 10201

  題意:過n個加油站,沒站油價不等,問達到目的地的最小花費,其實100L油,到達終點至少100L油。

  設狀態dp(i,j)表示在第i個加油站有jL油的最小花費,初始dp(i,j)=min{dp(i,j),dp(i-1,j+dis(i,i-1))},然後根據油價嘗試更新dp(i,k),(k>j)。

  小心數據所給加油站並不是都在起點到終點的區間內。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
int pos[110]={0},pri[110];
long long dp[110][210];
int main()
{
	//freopen("in.txt","r",stdin);
	int  T;
	cin>>T;
	while(T--){
		int dis,pre=0,n=1;
		cin>>dis;getchar();
		char t;
		while((t=getchar())&&t!='\n'&&t!=EOF){
			pos[n]=t-'0';
			while((t=getchar())!=' ') pos[n]=pos[n]*10+t-'0';
			pri[n]=0;
			while((t=getchar())!='\n') pri[n]=pri[n]*10+t-'0';
			if(pos[n]>0&&pos[n]<dis) n++;
		}
		n--;
		bool is=true;
		for(int i=2;i<n;i++) if(pos[i]-pos[i-1]>200){
			is=false;break;
		}
		if(pos[1]>100) is=false;
		if(pos[n]-pos[n-1]>100) is=false;
		if(!is) {printf("Impossible\n");if(T) cout<<endl;continue;}
		memset(dp,-1,sizeof(dp));
		dp[0][100]=0;
		for(int i=1;i<=n;i++){
			int d=pos[i]-pos[i-1];
			for(int j=0;d+j<=200;j++) if(dp[i-1][j+d]!=-1){
				if(dp[i][j]==-1) dp[i][j]=dp[i-1][j+d];
				else dp[i][j]=min(dp[i][j],dp[i-1][j+d]);

				for(int k=1;j+k<=200;k++){
					if(dp[i][j+k]==-1) dp[i][j+k]=dp[i][j]+pri[i]*k;
					else dp[i][j+k]=min(dp[i][j+k],dp[i][j]+pri[i]*k);
				}
			}
		}
		long long ans=dp[n][dis-pos[n]+100];
		if(ans==-1) cout<<"Impossible"<<endl;
		else cout<<ans<<endl;
		if(T) cout<<endl;
	}
	return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章