[Codeforces 988.F] Rain and Umbrellas(序列dp)

F. Rain and Umbrellas

time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

Polycarp lives on a coordinate line at the point x=0 x = 0 . He goes to his friend that lives at the point x=a x = a . Polycarp can move only from left to right, he can pass one unit of length each second.

Now it’s raining, so some segments of his way are in the rain. Formally, it’s raining on n n non-intersecting segments, the i-th segment which is in the rain is represented as [li,ri] [ l i , r i ] ( 0li<ria 0 ≤ l i < r i ≤ a ).

There are m m umbrellas lying on the line, the i-th umbrella is located at point xi x i ( 0xia 0 ≤ x i ≤ a ) and has weight pi p i . When Polycarp begins his journey, he doesn’t have any umbrellas.

During his journey from x=0 x = 0 to x=a x = a Polycarp can pick up and throw away umbrellas. Polycarp picks up and throws down any umbrella instantly. He can carry any number of umbrellas at any moment of time. Because Polycarp doesn’t want to get wet, he must carry at least one umbrella while he moves from x x to x+1 if a segment [x,x+1] [ x , x + 1 ] is in the rain (i.e. if there exists some i i such that lix and x+1ri x + 1 ≤ r i ).

The condition above is the only requirement. For example, it is possible to go without any umbrellas to a point where some rain segment starts, pick up an umbrella at this point and move along with an umbrella. Polycarp can swap umbrellas while he is in the rain.

Each unit of length passed increases Polycarp’s fatigue by the sum of the weights of umbrellas he carries while moving.

Can Polycarp make his way from point x=0 x = 0 to point x=a x = a ? If yes, find the minimum total fatigue after reaching x=a x = a , if Polycarp picks up and throws away umbrellas optimally.

Input

The first line contains three integers a a , n and m m (1a,m2000,1na2) — the point at which Polycarp’s friend lives, the number of the segments in the rain and the number of umbrellas.

Each of the next n n lines contains two integers li and ri r i ( 0li<ria 0 ≤ l i < r i ≤ a ) — the borders of the i i -th segment under rain. It is guaranteed that there is no pair of intersecting segments. In other words, for each pair of segments i and j j either ri<lj or rj<li r j < l i .

Each of the next m m lines contains two integers xi and pi p i ( 0xia 0 ≤ x i ≤ a , 1pi105 1 ≤ p i ≤ 10 5 ) — the location and the weight of the i i -th umbrella.

Output

Print “-1” (without quotes) if Polycarp can’t make his way from point x=0 to point x=a x = a . Otherwise print one integer — the minimum total fatigue after reaching x=a x = a , if Polycarp picks up and throws away umbrellas optimally.

Examples

inputoutput
10 2 4
3 7
8 10
0 10
3 4
8 1
1 2
14
10 1 1
0 9
0 5
45
10 1 1
0 9
1 5
-1

Note

In the first example the only possible strategy is to take the fourth umbrella at the point x=1 x = 1 , keep it till the point x=7 x = 7 (the total fatigue at x=7 x = 7 will be equal to 12 12 ), throw it away, move on from x=7 x = 7 to x=8 x = 8 without an umbrella, take the third umbrella at x=8 and keep it till the end (the total fatigue at x=10 x = 10 will be equal to 14 14 ).

In the second example the only possible strategy is to take the first umbrella, move with it till the point x=9 x = 9 , throw it away and proceed without an umbrella till the end.


解题思路

这肯定是一道 dp 题。
注意题目是从 0 0 位置开始的,下列解法均先把所有位置右移了1格

首先有一个很显然的贪心:不可能同时拿着多把伞。
然后预处理一下哪些地方下雨,哪些地方有伞,每把伞在什么位置 O(na+m)

下面是 dp:
考虑到不同的状态取决于当前所在位置和当前拿着的伞,令 dp[i][j] d p [ i ] [ j ] 表示走到 i i 时拿着第 j 把伞( j=0 j = 0 表示没拿伞),分情况转移(已知 dp[i][j] d p [ i ] [ j ] ,刷表法):

  • 拿着第 j j 把伞走到 i+1 dp[i+1][j]=min(dp[i+1][j],dp[i][j]+weight[j]) d p [ i + 1 ] [ j ] = m i n ( d p [ i + 1 ] [ j ] , d p [ i ] [ j ] + w e i g h t [ j ] )
    前提: j0 j ≠ 0
  • 放下第 j j 把伞走到 i+1 dp[i+1][0]=min(dp[i+1][0],dp[i][j]) d p [ i + 1 ] [ 0 ] = m i n ( d p [ i + 1 ] [ 0 ] , d p [ i ] [ j ] )
    前提: i i 处不下雨
  • 拿起 i 处的最轻的伞(假设是第 k k 把伞)走到 i+1 dp[i+1][k]=min(dp[i+1][k],dp[i][j]+w[k] d p [ i + 1 ] [ k ] = m i n ( d p [ i + 1 ] [ k ] , d p [ i ] [ j ] + w [ k ]
    前提: i i 处有伞

边界条件为 dp[0][0]=0
答案就是 mini=0mdp[a][i] min i = 0 m d p [ a ] [ i ]

坑点:同一个位置可以有多把伞!

时间复杂度 O(na) O ( n ⋅ a )


Code

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 2005;
bool rain[N];
struct Umbrella{
    int pos, w;
}umb[N];
int a, n, m, x, y, umbre[N];
int dp[N][N], ans = 1e9;

int main(){
    scanf("%d%d%d", &a, &n, &m);
    a++;
    for(int i = 1; i <= n; i++){
        scanf("%d%d", &x, &y);
        x++, y++;
        for(int j = x; j < y; j++)
            rain[j] = 1;
    }
    for(int i = 1; i <= m; i++){
        scanf("%d%d", &x, &y);
        x++;
        umb[i].pos = x;
        umb[i].w = y;
        if(!umbre[x] || (umbre[x] && y < umb[umbre[x]].w))
            umbre[x] = i;
    }
    memset(dp, 0x3f, sizeof dp);
    dp[0][0] = 0;
    for(int i = 0; i < a; i++){
        for(int j = 0; j <= m; j++){
            if(umb[j].pos > i)  continue;
            if(j)
                dp[i+1][j] = min(dp[i+1][j], dp[i][j] + umb[j].w);
            if(!rain[i])
                dp[i+1][0] = min(dp[i+1][0], dp[i][j]);
            if(umbre[i])
                dp[i+1][umbre[i]] = min(dp[i+1][umbre[i]], dp[i][j] + umb[umbre[i]].w);
        }
    }
    for(int i = 0; i <= m; i++)
        ans = min(ans, dp[a][i]);
    if(ans == 1e9)  puts("-1");
    else    printf("%d\n", ans);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值