Codeforces 988F. 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;
}
posted @ 2018-06-16 20:13  ninding  阅读(169)  评论(0编辑  收藏  举报