uva 10201 Adventures in Moving - Part IV(dp)

题意:

一辆车从起点走到终点,途中有些加油站,给出每个加油站距离和油价,最后求从起点到终点最小费用,其中在起点有100升油,要求到终点至少也还有100升油。

解法:

dp[i][j]记录走到第i站升j升油的最小费用,用当前的合法状态去更新后一个状态。
dp[i][j]表示到达第i个加油站剩余油量为j时的最小花费
特殊地,dp[n][j]表示到达终点剩余油量为j时的最小花费
状态转移:(设w[i]为每个加油站的位置,p[i]为油单价)
行驶:dp[i][j-(w[i]-w[i-1])] = dp[i-1][j] (0

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
char line[50];
int d[105],f[105];
int dp[105][205];
int dist;
int n;
int main() {
    int T ,d1,f1;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&dist); getchar();
        n = 1;
        while(gets(line) && line[0] != '\0') {
            sscanf(line,"%d%d",&d1,&f1);
            if(d1 > dist)
                continue;
            if(d[n-1] == d1 && f[n-1] < f1) //如果有两个相同的站点,且费用比前面的小
                f[n-1] = f1;
            else if(d[n-1]<d1) {
                d[n]=d1;
                f[n]=f1;
                n++;
            }
        }
        d[0] = 0;
        d[n] = dist;

        memset(dp,INF,sizeof(dp));
        dp[0][100] = 0;
        for(int i = 1; i <= n; i++) {
            int dis = d[i] - d[i-1];
            for(int j = dis; j <= 200; j++) {
                dp[i][j-dis] = dp[i-1][j];
            }
            if(i != n)
                for(int j = 1; j <= 200; j++) {
                    dp[i][j] = min(dp[i][j] , dp[i][j-1] + f[i]);
                }

        }
        if(dp[n][100] != INF)
            printf("%d\n",dp[n][100]);
        else
            puts("Impossible");
        if(T)
            printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值