7-7 加油站之最小加油次数 (15 分)

7-7 加油站之最小加油次数 (15 分)

题目:
一辆汽车要行驶L单位距离。最开始时,汽车上有P单位汽油,每向前行驶1单位距离消耗1单位汽油。如果在途中车上的汽油耗尽,汽车就无法继续前行,即无法到达终点。途中共有N个加油站,加油站提供的油量有限,汽车的油箱无限大,无论加多少油都没问题。给出每个加油站距离终点的距离L和能够提供的油量P,问卡车从起点到终点至少要加几次油?如果不能到达终点,输出-1。

输入格式:
第一行输入N; 接下来N行分别输入两个整数L和P。 最后一行表示汽车的起点到终点的位置L和油量P。

输出格式:
输出到达城镇所需的最少站点数,如果车无法到达城镇,则输出-1。
在这里插入图片描述
思路:从当前点出发,深搜每个可以去的满足条件的点,只要是不满足的点,得到的结果m>=99999,最后都会返回min(99999),所以判断是否为99999就可以判断是否可以到达终点,无法到达返回-1。
代码:

#include <stdio.h>
#include <stdlib.h>
int n,sl,sw;
struct node
{
    int l,w;
}a[10010];
int dfs(int x,int lastw,int lastl)
{
    if(lastw>=lastl)//判断当前点能否直接到终点
        return 0;
    int min=99999;//记录最小值
    for(int i=x+1;i<=n+1;i++)//判断下一次停下的位置
    {
        if(lastl-a[i].l>lastw)//如果到这个点的距离值大于油量,退出循环(因为后面的距离更大)
            break;
        else//否则,选该点
        {
            int m=dfs(x+1,lastw-(lastl-a[i].l)+a[i].w,a[i].l)+1;//向下深搜,只要有一个不满足的点得到的m都会大于999999(例如:d=999999+1)
            if(m<min)//判断是否是最小值
                min=m;
        }
    }
    return min;//若不能到下一个点返回99999
}
int inc(struct node *a, struct node *b)//排序大的在前,小的在后
{
	 return (*b).l -(*a).l;
}
int main()
{
    scanf("%d",&n);
    for(int i=n;i>=0;i--)
        scanf("%d%d",&a[i].l,&a[i].w);
    qsort(a,n+1,sizeof(struct node),inc);
    int min=dfs(0,a[0].w,a[0].l);
    if(min==99999)//只要是不能通过,得到的值都大于等于99999,所以将min值改为-1
        min=-1;
    printf("%d",min);
    return 0;
}

没pta测试过,但是满足样例
在这里插入图片描述

在这里插入图片描述

优化改为动态规划(代码如下):

#include <stdio.h>
#include <stdlib.h>
int n,sl,sw;
struct node
{
    int l,w;
}a[10010];
int vis[10010][10010];//存储记录下的最小值
int dfs(int x,int lastw,int lastl)
{
    if(lastw>=lastl)//判断当前点能否直接到终点
        return 0;
    if(vis[lastw][lastl]!=0)//如果当前情况下的最小值已记录,直接返回这个最小值
        return vis[lastw][lastl];
    int min=99999;//记录最小值
    for(int i=x+1;i<=n+1;i++)//判断下一次停下的位置
    {
        if(lastl-a[i].l>lastw)//如果到这个点的距离值大于油量,退出循环(因为后面的距离更大)
            break;
        else//否则,选该点
        {
            int m=dfs(x+1,lastw-(lastl-a[i].l)+a[i].w,a[i].l)+1;//向下深搜,只要有一个不满足的点得到的m都会大于999999(例如:d=999999+1)
            if(m<min)//判断是否是最小值
                min=m;
        }
    }
    return vis[lastw][lastl]=min;//若不能到下一个点返回99999,   记录下当前情况下的最小值
}
int inc(struct node *a, struct node *b)//排序大的在前,小的在后
{
	 return (*b).l -(*a).l;
}
int main()
{
    scanf("%d",&n);
    for(int i=n;i>=0;i--)
        scanf("%d%d",&a[i].l,&a[i].w);
    qsort(a,n+1,sizeof(struct node),inc);
    int min=dfs(0,a[0].w,a[0].l);
    if(min==99999)//只要是不能通过,得到的值都大于等于99999,所以将min值改为-1
        min=-1;
    printf("%d",min);
    return 0;
}


202111071619日

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baibai___

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值