dp(uva10201Adventures in Moving - Part IV)

来源:互联网 发布:小米快盘数据如何迁移 编辑:程序博客网 时间:2024/06/06 03:24

题意:有一辆车,原始装有100L汽油,到达距离为d的目的地,中间有x个加油站,每升油的价格为p。

汽车每跑一公里耗油1L,求到达目的地油箱仍然有100L的最小花费。车的最大容量为200

思路:dp[i][j]表示从第i个加油站出发时,邮箱里有j省油的最小花费

那么可以得到递推公式,首先dp[i][j]最小值从dp[i-1][j+tmp]推得,在第i个加油站,可以选择加k省油(0<=k<=200),得到从i出发时有j的最优质

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;const int maxn=10010;const int maxm=110;int N,L,dp[maxm][maxm*2];struct node{    int x,p;    bool operator<(const node &a)const    {        return x<a.x;    }}a[maxm];void init(){    char b[maxm];    gets(b);    sscanf(b, "%d", &L);    N = 0;    while(gets(b) != NULL)    {        if(b[0] == '\0')            break;        ++N;        sscanf(b,"%d%d", &a[N].x, &a[N].p);        if(a[N].x<0||a[N].x>L)            --N;    }}int main(){    int T;    scanf("%d",&T);    bool first=true;    while(T--)    {        if(first)first=false;        else printf("\n");        scanf("%d",&L);        init();        sort(a+1,a+N+1);        memset(dp,INF,sizeof(dp));        dp[0][100]=0;        for(int i=1;i<=N;i++)        {            int tmp=a[i].x-a[i-1].x;            for(int j=0;j+tmp<=200;j++)                dp[i][j]=min(dp[i][j],dp[i-1][j+tmp]);            for(int j=1;j<=200;j++)                for(int k=0;k<=j;k++)                    dp[i][j]=min(dp[i][j],dp[i][k]+(j-k)*a[i].p);        }        if(L-a[N].x>100||dp[N][100+L-a[N].x]>=INF)printf("Impossible\n");        else printf("%d\n",dp[N][100+L-a[N].x]);    }    return 0;}





0 0
原创粉丝点击