Codeforces F. Rain and Umbrellas

Posted zhangjiuding

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces F. Rain and Umbrellas相关的知识,希望对你有一定的参考价值。

解题思路:动态规划

  1. 遍历点i,如果从前一个点i-1走到这个点i不需要伞,则疲劳值不变dp[i] = dp[i-1]。
  2. 如果前一个点i-1走到这一个点i需要伞,则从前面找一把伞。
  3. 即遍历前面的每个点j,如果点j处有伞,dp[i] = min(dp[i], dp[j]+(i-j)*fig[j])。fig[j]意为第j个点出伞所需要的疲劳值。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll; 

bool seg[2010]; //seg[i]=true表示从i-1走到i需要伞 
int umb[2010];  //umb[i]如果不为INT_MAX表示第i个位置有伞,且umb[i]是这个点所有伞疲劳值的最小值 
int dp[2010];   //dp[i]表示走到第i个点最少需要的疲劳值 

int main(){
    ios::sync_with_stdio(false);
    int a,n,m;
    cin >> a >> n >> m;
    int k1,k2;
    //将seg[k1+1,k2]填充为true,边界考虑清楚,注意seg后面的注释 
    for(int i = 1;i <= n; ++i) cin >> k1 >> k2, fill(seg+k1+1,seg+k2+1,true);
    //umb表示伞 
    fill(umb, umb+2010, INT_MAX);
    for(int i = 1;i <= m; ++i) cin >> k1 >> k2, umb[k1] = min(umb[k1],k2);
    fill(dp+1, dp+2010, INT_MAX/2);
    for(int i = 1;i <= a; ++i){
        //如果从i-1走到i需要伞,则从前面找一把伞 
        if(seg[i]){
            for(int j = i-1;j >= 0; --j)
                if(umb[j] != INT_MAX)
                    dp[i] = min(dp[i], dp[j]+(i-j)*umb[j]);
        }else   //不需要伞,疲劳值不变 
            dp[i] = dp[i-1];
    }
    if(dp[a] == INT_MAX/2) dp[a] = -1;
    cout << dp[a] << endl;
    return 0;
}

以上是关于Codeforces F. Rain and Umbrellas的主要内容,如果未能解决你的问题,请参考以下文章

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

Codeforces Round #491 (Div. 2) F. Concise and clear

Codeforces 908 F. New Year and Rainbow Roads(思维)

Codeforces 908 F. New Year and Rainbow Roads(思维)

Codeforces 988F Rain and Umbrellas(DP)

F. Omkar and Akmar游戏,组合,逆元—— Codeforces Round #724 (Div. 2)