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日