F. Rain and Umbrellas——codeforces

参考出处:https://blog.csdn.net/haipai1998/article/details/80552571

外加自己的补充。前人栽树,后人乘凉。


Polycarp lives on a coordinate line at the point x=0x=0. He goes to his friend that lives at the point x=ax=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 nn non-intersecting segments, the ii-th segment which is in the rain is represented as [li,ri][li,ri] (0li<ria0≤li<ri≤a).

There are mm umbrellas lying on the line, the ii-th umbrella is located at point xixi (0xia0≤xi≤a) and has weight pipi. When Polycarp begins his journey, he doesn't have any umbrellas.

During his journey from x=0x=0 to x=ax=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 xx to x+1x+1 if a segment [x,x+1][x,x+1] is in the rain (i.e. if there exists some ii such that lixli≤x and x+1rix+1≤ri).

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=0x=0 to point x=ax=a? If yes, find the minimum total fatigue after reaching x=ax=a, if Polycarp picks up and throws away umbrellas optimally.

Input

The first line contains three integers aann and mm (1a,m2000,1na21≤a,m≤2000,1≤n≤⌈a2⌉) — 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 nn lines contains two integers lili and riri (0li<ria0≤li<ri≤a) — the borders of the ii-th segment under rain. It is guaranteed that there is no pair of intersecting segments. In other words, for each pair of segments ii and jj either ri<ljri<lj or rj<lirj<li.

Each of the next mm lines contains two integers xixi and pipi (0xia0≤xi≤a1pi1051≤pi≤105) — the location and the weight of the ii-th umbrella.

Output

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

Examples:

input:

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

output:

14

input:

10 1 1
0 9
0 5

output:

45

input:

10 1 1
0 9
1 5

output:

-1

题意:[0,a]的区间内,有些区间[l,r]被雨淋湿了,必须要有雨伞才能通过。每一把伞对应一个位置pos,重量wight 。  问想从0出发走到a,不被淋湿至少的w*dis是多少。他可以携带任意一把伞(只要到了伞被放置的位置),伞可以任意时刻丢弃或者拾起(只要到了伞被放置的位置)。如果一定会被淋到雨,输出-1。


解决思路:定义dp[n],表示为前n个点,不被淋到雨的最小的携带wight*dis。

         定义rain[n],表示为在第n个点是否下雨,1表示此点下雨,0表示此点不会。

        定义wi[n],表示伞在是否在第n个点,(值不为0即为在)相应的值代表为伞重。

        状态转移方程dp[i]=dp[i-1] ( rain[i-1]==0)

                    dp[i]=dp[j]+(i-j)*wi[j] (rain[i-1]==1) 

代码如下:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
LL dp[2005],wi[2005];
bool rain[2005];
int main()
{
    LL a,m,n;
    while(~scanf("%lld%lld%lld",&a,&n,&m))
    {
        memset(rain,false,sizeof(rain)); ///都初始化为不下雨
        memset(wi,0,sizeof(wi));
        for(int i=1;i<=n;i++)
        {
            LL l,r;
            scanf("%lld%lld",&l,&r);
            for(int i=l;i<r;i++)
                rain[i]=true;
        }
        for(int i=1;i<=m;i++)
        {
            LL xi,pi;
            scanf("%lld%lld",&xi,&pi);
            if(!wi[xi]) wi[xi]=pi;   ///判重,题目经常来坑
            else wi[xi]=min(wi[xi],pi);
        }
        fill(dp,dp+2005,INF);  ///
        dp[0]=0;  ///注意次处初始化
        for(int i=1;i<=a;i++)
        {
           if(!rain[i-1]) dp[i]=dp[i-1];
           else{

                for(int j=0;j<i;j++)
                {
                    if(wi[j]){
                        dp[i]=min(dp[i],dp[j]+(LL)(i-j)*wi[j]);
                    }
                }
           }
        }

        if(dp[a]==INF) printf("-1\n");///只要有一个下雨的地方j没用伞,那么此点的dp[j]=INF,
        ///后面一连串的点dp[i]都只能是INF,这点的值要不就转移给下一个(rain[i]=0),要不就在min时,dp[j]=INF,dp[j]+(i-j)*wi[j]>INF,
        ///所以还是INF
        else printf("%lld\n",dp[a]);///

    }
    return 0;
}


我的标签:做个有情怀的程序员。

猜你喜欢

转载自blog.csdn.net/ljd201724114126/article/details/80561237