【CodeForces】【DP】988F-Rain and Umbrellas

CodeForces 988F Rain and Umbrellas

题目

◇题目传送门◆

题目大意

有一个人在数轴上的原点,他想到达 A A 点,但路上有N区间在下雨,在下雨的区间内必须打伞,他却没有伞。但是路上有 M M 把伞,每个伞有两个属性——x,p x x 表示伞的位置,p表示伞的重量。每携带 1 1 单位重量的伞走1个单位长度需要消耗 1 1 单位体力,求从0 A A 消耗的最少体力。

思路

一道~~裸且简单的~~DP题。

我们设w[i]为位于 i i 点的伞的重量值,若值为,则该处无伞。 rain[i] r a i n [ i ] 表示 i i 段是否下雨。设F[i]为由 0 0 ~i的最少体力消耗。

则得出状态转移方程:

F[i]={F[i1](rain[i]=false,1iA)min{F[j]+(ij)×w[j]}(w[j],0j<i,1iA) F [ i ] = { m i n { F [ j ] + ( i − j ) × w [ j ] } ( w [ j ] ≠ ∞ , 0 ≤ j < i , 1 ≤ i ≤ A ) F [ i − 1 ] ( r a i n [ i ] = f a l s e , 1 ≤ i ≤ A )

答案即为 F[A] F [ A ]

实现细节

注意:一个点可能有多把伞,我们只需取重量最小的那一个。

正解代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Maxn=2000;
const long long INF=1e18;
int A,N,M;

long long dp[Maxn+5],W[Maxn+5];
bool Is_rain[Maxn+5];

int main() {
    #ifdef LOACL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    fill(dp,dp+Maxn+1,INF);
    fill(W,W+Maxn+1,INF);
    dp[0]=0;

    scanf("%d %d %d",&A,&N,&M);
    for(int i=1;i<=N;i++) {
        int l,r;
        scanf("%d %d",&l,&r);
        for(int j=l;j<r;j++)
            Is_rain[j]=true;
    }
    for(int i=1;i<=M;i++) {
        int x;
        long long w;
        scanf("%d %lld",&x,&w);
        W[x]=min(W[x],w);
    }

    for(int i=1;i<=A;i++)
        if(!Is_rain[i-1]) {
            dp[i]=dp[i-1];
        } else {
            for(int j=i-1;j>=0;j--)
                if(W[j]!=INF)
                    dp[i]=min(dp[i],dp[j]+(i-j)*W[j]);
        }

    printf("%lld\n",dp[A]==INF?-1:dp[A]);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值