Codeforces 988F Rain and Umbrellas(DP)
题目链接:http://codeforces.com/contest/988/problem/F
题目大意:
有三个整数a,n,m,a是终点坐标,给出n个范围(l,r)表示这块区域下雨,m把伞(p,w)在点p有重量为w的伞。
小明可以携带任意数量的伞,经过下雨处时必须要撑伞,小明每走一个单位长度消耗的体力与他所携带伞的重量相同,
求小明从0~a所需消耗的最少体力,若无解则输出-1。
解题思路:
第一种解法:
设dp[i]表示到达i点所需花费的最少体力,rain[i]表示第i段是否下雨(注意是段不是点),ub[j]表示j点放置的伞的重量。
则当rain[i-1]=false时,dp[i]=dp[i]-1
rain[i-1]=true是,dp[i]=min{dp[j]+(i-j)*ub[j]},(ub[j]!=1e18且j<=i-1)
复杂度O(n^2)
第二种解法:
设dp数组,
dp[i][0]表示到达第i段不拿伞最小花费
dp[i][1]表示到达第i段拿伞最小化费
dp[i][2]表示到达第i段拿最小重量的伞的最小化费
然后不想说了,各种递推就是了。。。
复杂度O(n)
代码:
解法一:
#include<bits/stdc++.h>
#define lc(a) (a<<1)
#define rc(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define _for(i,start,end) for(int i=start;i<=end;i++)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long LL;
const int N=2e3+;
const int INF=0x3f3f3f3f;
const double eps=1e-; LL dp[N],ub[N];
bool rain[N]; int main(){
FAST_IO;
int a,n,m;
cin>>a>>n>>m;
for(int i=;i<N;i++){
dp[i]=ub[i]=1e18;
}
for(int i=;i<=n;i++){
int l,r;
cin>>l>>r;
if(l>r) swap(l,r);
for(int j=l;j<=r-;j++){
rain[j]=true;
}
}
for(int i=;i<=m;i++){
LL p,w;
cin>>p>>w;
ub[p]=min(ub[p],w);
}
dp[]=;
for(int i=;i<=a;i++){
if(!rain[i-]){
dp[i]=dp[i-];
}
else{
for(int j=i-;j>=;j--){
if(ub[j]!=1e18)
dp[i]=min(dp[i],dp[j]+(i-j)*ub[j]);
}
}
}
if(dp[a]==1e18)
cout<<-<<endl;
else
cout<<dp[a]<<endl;
return ;
}
解法二:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<string.h>
#include<cctype>
#include<math.h>
#include<stdlib.h>
#include<stack>
#include<queue>
#include<set>
#include<map>
#define lc(a) (a<<1)
#define rc(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define _for(i,start,end) for(int i=start;i<=end;i++)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long LL;
const int N=2e3+;
const int INF=0x3f3f3f3f;
const double eps=1e-; bool rain[N],flag[N];
LL dp[N][],ub[N];
//dp[i][0]表示到达第i段不拿伞最小花费
//dp[i][1]表示到达第i段拿伞最小化费
//dp[i][2]表示到达第i段拿最小重量的伞的最小化费 int main(){
FAST_IO;
int a,n,m;
cin>>a>>n>>m;
for(int i=;i<N;i++){
ub[i]=dp[i][]=dp[i][]=dp[i][]=1e18;
}
for(int i=;i<=n;i++){
int l,r;
if(l>r)
swap(l,r);
cin>>l>>r;
for(int j=l;j<=r-;j++){
rain[j]=true;
}
}
for(int i=;i<=m;i++){
LL p,w;
cin>>p>>w;
ub[p]=min(ub[p],w);
} if(!rain[])
dp[][]=;
dp[][]=dp[][]=ub[];
LL mmin=ub[],now=ub[];
for(int i=;i<=a-;i++){
if(ub[i]){
mmin=min(ub[i],mmin);
now=min(ub[i],now);
}
LL t=min(dp[i-][]+now,dp[i-][]+mmin);
dp[i][]=t;
if(t==dp[i-][]+mmin)
now=mmin;
dp[i][]=dp[i-][]+mmin; //下雨
if(rain[i]){
//有伞
if(ub[i]){
dp[i][]=min(dp[i-][]+ub[i],dp[i][]);
if(dp[i][]==dp[i-][]+ub[i])
now=ub[i];
if(mmin==ub[i]){
dp[i][]=min(dp[i-][]+mmin,dp[i][]);
}
}
}
//不下雨
else{
dp[i][]=min(dp[i-][],dp[i-][]);
//有伞
if(ub[i]){
dp[i][]=min(dp[i-][]+ub[i],dp[i][]);
if(dp[i][]==dp[i-][]+ub[i])
now=ub[i];
if(mmin==ub[i]){
dp[i][]=min(dp[i-][]+mmin,dp[i][]);
}
}
}
}
LL ans=min(dp[a-][],dp[a-][]);
if(ans!=1e18)
cout<<ans<<endl;
else
cout<<-<<endl;
return ;
}
Codeforces 988F Rain and Umbrellas(DP)的更多相关文章
- Codeforces 988F. Rain and Umbrellas
解题思路:动态规划 遍历点i,如果从前一个点i-1走到这个点i不需要伞,则疲劳值不变dp[i] = dp[i-1]. 如果前一个点i-1走到这一个点i需要伞,则从前面找一把伞. 即遍历前面的每个点j, ...
- Codeforces Round #486 (Div. 3) F. Rain and Umbrellas
Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...
- CodeForces 988 F Rain and Umbrellas
Rain and Umbrellas 题意:某同学从x=0的点走到x=a的点,路上有几段路程是下雨的, 如果他需要经过这几段下雨的路程, 需要手上有伞, 每一把伞有一个重量, 求走到重点重量×路程的最 ...
- [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)
[BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...
- Rain and Umbrellas(dp)
题目链接 http://codeforces.com/problemset/problem/988/F 令dp[i][j]为走到目标为i处,手里拿着第j把伞,同时注意,在某处可能存在不止一把伞 #in ...
- Codeforces Round #486-F.Rain and Umbrellas题解
一.题目链接:http://codeforces.com/contest/988/problem/F 二.题面 三.思路 很明显而且比较能想到的$dp$. 四.代码实现 #include<bit ...
- codeforces 721C (拓排 + DP)
题目链接:http://codeforces.com/contest/721/problem/C 题意:从1走到n,问在时间T内最多经过多少个点,按路径顺序输出. 思路:比赛的时候只想到拓排然后就不知 ...
- codeforces 711C Coloring Trees(DP)
题目链接:http://codeforces.com/problemset/problem/711/C O(n^4)的复杂度,以为会超时的 思路:dp[i][j][k]表示第i棵数用颜色k涂完后bea ...
- codeforces 55D - Beautiful numbers(数位DP+离散化)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
随机推荐
- listview android:cacheColorHint,android:listSelector属性作用(转)
ListView是常用的显示控件,默认背景是和系统窗口一样的透明色,如果给ListView加上背景图片,或者背景颜色时,滚动时listView会黑掉, 原因是,滚动时,列表里面的view重绘时,用的依 ...
- mac下Android Studio使用及快捷键
1.Android Studio使用及快捷键 (1)我们新建一个项目后进入界面,左侧可以选择Project或Android,一般选Project会比较习惯以前eclipse的显示 (2)点击左上角An ...
- ACM比赛_注意
ACM比赛_注意: 比赛前: 1.前一天早一点睡觉 2.避免参加激烈的活动,以免比赛时精力不足; 3.少喝水,并提前上厕所; 4.把账号,密码都准备好,放在txt中 5.提前创建多个程序(etc.10 ...
- C标准库函数--文件IO操作函数。
C标准库文件读写函数总结:都是对文件流进行输入输出的函数分为对文件的有格式读写以及无格式读写 一.文件的无格式读写根据每次读写字符的数量,分为三类:1.按字符读写文件 按字符读有三个函数:以下三个函数 ...
- PHP_EOL 写入字符串换行 , php获取毫秒 microtime
private function miclog($t1,$t2,$name){ $lasttime = ($t2 - $t1).'ms'; $content = date('Y-m-d H:i:s', ...
- Linux设备驱动之Ioctl控制
大部分驱动除了需要具备读写设备的能力之外,还需要具备对硬件控制的能力. 一.在用户空间,使用ioctl系统调用来控制设备,原型如下: int ioctl(int fd,unsigned long cm ...
- 51nod 1181 质数中的质数
1181 质数中的质数(质数筛法) 题目来源: Sgu 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 如果一个质数,在质数列表中的编号也是质数,那么就称 ...
- Linux块设备和字符设备
块设备:系统能够随机无序访问固定大小的数据片的设备,这些数据片称为块.块设备是以固定大小长度来传送资料的,它使用缓冲区暂存数据,时机成熟后从缓存中一次性写入到设备或者从设备中一次性放到缓存区.常见的块 ...
- [译]Quartz.NET 框架 教程(中文版)2.2.x 之第六课 CronTrigger
第六课 CronTrigger CronTrigger比SimpleTrigger更常用,当你需要一个基于日历般概念的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间. 使用Simp ...
- Grep学习笔记
Grep(Global search Regular Expression and Print out the line)是一种强大的文本搜索工具. 1. 正则表达式的基本组成部分 正则表达式 描述 ...