Hitoj 3213 Minimize the cost【Dp】

针对学生Bob每天需乘坐公交从家到学校的场景,本篇博客介绍了一种算法来计算Bob到达学校所需的最小公交票费。考虑了不同公交线路的运行区间,并通过动态规划求解最优路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Minimize the cost

My Tags  (Edit)
Source : 16春校赛
Time limit : 3 secMemory limit : 131072 M

Submitted : 28, Accepted : 9

Description

  Bob is a student of HIT, but his home is so far from school that he has to take bus to school every weekday morning. To make the problem simple, we assume that the way between Bob’s home and the school is a straight line and Bob’s home is located on 0 and the school is located on S. There are n buses running back and forth between the interval [li, ri] (including li and ri) and for every bus the tickets cost one dollar.

  Give the school’s position S and n buses’s interval [li, ri], you should calculate the minimum tickets fee Bob should pay to get to school from home. If Bob can’t get to school by bus, the answer should be -1.

Note we don’t care about the departure time of the buses.

 

Input

The first line contains a integer T( T <= 50), then T cases follows.

 

In each case, there are 2 parts of input.

The first part contains 2 integers S, n in a single line

The second part contains n lines, each line contains two integers li and ri.

 

1 <= T <= 50

0 < S <= 10000

0 < n <= 1000

0 <= li <= ri <= S

Output

For each case, you should output the minimum tickets fee Bob should pay to get to school from home. If Bob can’t get to school by bus, output -1.

 

 

Sample

Input

Output

2

10 3

0 5

5 10

0 10

10 2

0 5

6 10

 

1

-1


题目大意:

Bob的家在坐标0位子,目标是要到S位子,现在有n趟公交,起点是L,终点是R.每一趟公交的花费都是1.

问Bob从家到目标S的最小花费。


思路:


设定dp【i】表示到位子i的最小花费。

那么dp【i】=min(dp【LL~i-1】+1,dp【i】)这里LL表示的是能够到达i这个点的所有班车的起始位子的最小值。

后台数据不多也很水,直接O(n^2)就能过,如果TLE了,再套个线段树查询区间最小值也是很滋滋的。


Ac代码:

#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
vector<int >mp[105000];
int dp[105000];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++)mp[i].clear();
        for(int i=0;i<=n;i++)dp[i]=0x3f3f3f3f;
        dp[0]=0;
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if(x>y)swap(x,y);
            mp[y].push_back(x);
        }
        for(int i=1;i<=n;i++)
        {
            int minn=0x3f3f3f3f;
            for(int j=0;j<mp[i].size();j++)
            {
                int u=mp[i][j];
                minn=min(u,minn);
            }
            if(minn==0x3f3f3f3f)continue;
            for(int j=minn;j<=i;j++)
            {
                dp[i]=min(dp[j]+1,dp[i]);
            }
        }
        if(dp[n]==0x3f3f3f3f)printf("-1\n");
        else
        printf("%d\n",dp[n]);
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值