Codeforces Round #486-F.Rain and Umbrellas题解

一、题目链接http://codeforces.com/contest/988/problem/F

二、题面

三、思路

  很明显而且比较能想到的$dp$。

四、代码实现

#include<bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
#define MAXN 2018
typedef pair<int, int> PII;
typedef long long LL;
int dest, n, m, p[MAXN], rain_len[MAXN];
PII rains[MAXN];
map<int, int> mp;
bool wet[MAXN];
LL b[MAXN], dp[MAXN][MAXN];
int main(){
//    freopen("input.txt", "r", stdin);
    int t1, t2;
    scanf("%d%d%d", &dest, &n, &m);
    for(int i = 1;i <= n;++i){
        scanf("%d%d", &t1, &t2);
        rains[i] = make_pair(t1, t2);
        fill(wet + t1, wet + t2, true);
    }
    sort(rains + 1, rains + n + 1);
    for(int i = 1;i <= m;++i){
        scanf("%d%d", &t1, &t2);
        if(mp.find(t1) != mp.end())mp[t1] = min(mp[t1], t2);
        else mp[t1] = t2;
    }
    m = 0;
    for(auto e : mp){
        t1 = e.fst, t2 = e.snd;
        b[++m] = t2, p[m] = t1;
    }
    b[m + 1] = 0, p[m + 1] = dest;
    for(int i = 1;i <= m;++i){
        for(int j = p[i + 1];j > p[i];--j){
            if(wet[j - 1]){
                rain_len[i] = j - p[i];
                break;
            }
        }
    }
    bool dry = 1;
    for(int i = 0;i < p[1];++i)dry &= !wet[i];
    if(!dry)return !printf("-1\n");
    else{
        memset(dp, 0x3f, sizeof(dp));
        dp[1][1] = 0;
        for(int i = 1;i <= m;++i){
            for(int j = 1;j <= i;++j){
                dp[i + 1][i + 1] = min(dp[i + 1][i + 1], dp[i][j] + b[j] * rain_len[i]);
                dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + b[j] * (p[i + 1] - p[i]));
            }
        }
        LL ans = *min_element(dp[m + 1], dp[m + 1] + MAXN + 1);
        cout << ans << endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/565261641-fzh/p/9223784.html