2019 GUDT RC 2 Problem G(题解)

原题

Problem G. Snow Boots

Input file: standard input

Output file: standard output

Time limit: 1 second

Memory limit: 256 megabytes

It’s winter on the farm, and that means snow! There are N tiles on the path from the farmhouse to the barn, conveniently numbered 1 . . . N, and tile i is covered in fi feet of snow.

Farmer John starts off on tile 1 and must reach tile N to wake up the cows. Tile 1 is sheltered by the farmhouse roof, and tile N is sheltered by the barn roof, so neither of these tiles has any snow. But to step on the other tiles, Farmer John needs to wear boots!

In his foul-weather backpack, Farmer John has B pairs of boots, numbered 1 . . . B. Some pairs are more heavy-duty than others, and some pairs are more agile than others. In particular, pair i lets FJ step in snow at most si feet deep, and lets FJ move at most di forward in each step.

Unfortunately, the boots are packed in such a way that Farmer John can only access the topmost pair at any given time. So at any time, Farmer John can either put on the topmost pair of boots (discarding his old pair) or discard the topmost pair of boots (making a new pair of boots accessible).

Farmer John can only change boots while standing on a tile. If that tile has f feet of snow, both the boots he takes off AND the boots he puts on must be able to withstand at least f feet of snow. Intermediate pairs of boots which he discards without wearing do not need to satisfy this restriction.

Help Farmer John minimize waste, by determining the minimum number of pairs of boots he needs to discard in order to reach the barn. You may assume that Farmer John is initially not wearing any boots.

Input

The first line contains two space-separated integers N and B (2 ≤ N, B ≤ 250).

The second line contains N space-separated integers. The ith integer is fi , giving the depth of snow on tile i (0 ≤ fi ≤ 109 ). It’s guaranteed that f1 = fN = 0.

The next B lines contain two space-separated integers each. The first integer on line i + 2 is si , the maximum depth of snow in which pair i can step. The second integer on line i + 2 is di , the maximum step size for pair i. It’s guaranteed that 0 ≤ si ≤ 109 and 1 ≤ di ≤ N − 1.

The boots are described in top-to-bottom order, so pair 1 is the topmost pair in FJ’s backpack, and so forth.

Output

The output should consist of a single integer, giving the minimum number of boots Farmer John needs to discard. It’s guaranteed that it will be possible for FJ to make it to the barn.

Example

input

10 4
0 2 8 3 6 7 5 1 4 0
2 3
4 2
3 4
7 1

output

2

题目大意

背景是讲下大雪,农夫要从家里出发到牛场,这条路上有n个板砖,每个板砖都有一个f值代表该板砖被雪覆盖的深度,第一个板砖和最后一块板砖在屋檐下所以没被雪覆盖即f[1]=f[n]=0,农夫有一个背包,背包里装着b双鞋,每双鞋都有两个属性s值和d值,s值是该鞋能踏的雪的最大深度为s,d值的穿着该鞋最多能一次跨多少个板砖,鞋是事先放好的,题目会从背包顶部从上往下给出每双鞋的属性,每次只能拿放在顶部的鞋,还有就是在一块板砖上换鞋的时候得保证将换的鞋要能够踩在当前的板砖上,也就是要换的鞋的s值得大于等于当前板砖的f值.问农夫到达最后一块板砖最少丢弃多少双鞋.ps:农夫被换的鞋将会被视为丢弃,如果要拿不是顶部的鞋,则该鞋的上面一些鞋也会被视为丢弃.

题目分析

该题可以用动态规划解决,设置dp[i]为在到达第i个板砖是已经丢弃的鞋的数,按照定义dp[0]=0,还有这道题有一个性质,就是农夫当前穿的鞋的编号是是丢的鞋的数加一,例如农夫到达第i个板砖是丢了8双鞋,则农夫必定穿着第九双鞋.了解这个性质后就可以着手更新dp数组了,先给出状态转移方程dp[i+k]=min(dp[i+k],j-1)(j从dp[i]+1→b)(k从1→d[i]),这里面的j是指当前要换的鞋(从dp[i]+1开始的原因是因为前面提到的性质),k是穿着这双鞋走多少步,就是在i为位置时,把所有能走的情况都遍历一遍,然后i++,同理再遍历,dp数组记录的是从开头位置走到当前位置的最优方案,即丢弃的鞋的数(最少).最后只需要输出dp[n].整体来说还是比较简单的,只要注意一些细节,把dp的if语句写好即可.

代码

 

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <string>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 const int INF=0x3f3f3f3f;
12 using namespace std;
13 
14 int dp[251];
15 int d[251];
16 long long f[251];
17 long long s[251];
18 
19 int main()
20 {
21     int n,b;
22     cin>>n>>b;
23     for(int i=1;i<=n;i++)
24         cin>>f[i];
25     for(int i=1;i<=b;i++)
26         cin>>s[i]>>d[i];
27     fill(dp,dp+251,INF); //初始化为inf方便更新
28     dp[1]=0;
29     for(int i=1;i<=n;i++)
30     {
31 
32         for(int j=dp[i]+1;j<=b;j++)
33         {
34             for(int k=1;k<=d[j];k++)
35             {
36                 //这里要注意防止数组越界和保证将换的鞋要能够踩在当前的板砖上
37                 if(i+k<=n&&f[i+k]<=s[j]&&f[i]<=s[j]) dp[i+k]=min(dp[i+k],j-1); 
38 
39             }
40 
41         }
42     }
43 
44     cout<<dp[n]<<endl;
45     return 0;
46 }

 

转载于:https://www.cnblogs.com/VBEL/p/10403386.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值