UVA 10201

/*
题意: 
有t组测试数据,每组数据的开始给出终点的位置,然后接下来有若干对数x,y,
x表示沿途的加油的位置,y表示每升油的价格。
每组数据间有一个空行。
汽车油箱容量是200升。 
汽车开始的时候在位置0,油箱里有100升汽油,
问最后到达终点,且油箱里还有100升汽油所需的最小花费是多少。

先开始没啥思路,后来问了学长又看了题解才想明白 T T 。 定义 dp[i][j]为到第 i 个加油站还剩 j 升油的最小花费。 首先有一部分状态是从第i-1个加油站得来的,即f[i][j]=f[i-1][j+d[i]-d[i-1]], 之后就是考虑第i个加油站买多少油会更划算, 那么状态转移方程为f[i][j]=min{min{f[i][k]+(j-k)*m[i]},f[i][j]} 如果终点离最后一个加油站超过100,则不可能做到还剩100升油, 因为油箱容量只有200升 。
*/ #include<cstdio> #include<cstring> #include<algorithm> #define INF 0x3f3f3f3f using namespace std; char s[100]; int f[110][210],d[110],p[110]; int main() { int t,l,cnt; gets(s); sscanf(s,"%d",&t); gets(s); while(t--) { gets(s); sscanf(s,"%d",&l); cnt=0; d[0]=0; while(gets(s)!=NULL) { if(s[0] == '\0') break; ++cnt; sscanf(s,"%d%d",&d[cnt],&p[cnt]); if(d[cnt]<0 || d[cnt] > l ) --cnt; } memset(f,0x3f,sizeof(f)); f[0][100]=0; for(int i=1;i<=cnt;i++) { int dis=d[i]-d[i-1]; for(int j=0;j+dis<=200;j++) if(f[i-1][j+dis] < f[i][j]) f[i][j]=f[i-1][j+dis] ; for(int j=1;j<=200;j++) { int tmp=INF; for(int k=0;k<j;k++) { int tp=f[i][k] + (j-k)*p[i]; if(tp<tmp) tmp=tp; } if(tmp<f[i][j]) f[i][j]=tmp; } } if(l-d[cnt]>100 || f[cnt][l+100-d[cnt]] == INF) printf("Impossible\n"); else printf("%d\n",f[cnt][l+100-d[cnt]]); if(t) printf("\n"); } return 0; }

 

posted @ 2015-10-21 20:03  Ember  阅读(161)  评论(0编辑  收藏  举报