题目链接: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)的更多相关文章

  1. Codeforces 988F. Rain and Umbrellas

    解题思路:动态规划 遍历点i,如果从前一个点i-1走到这个点i不需要伞,则疲劳值不变dp[i] = dp[i-1]. 如果前一个点i-1走到这一个点i需要伞,则从前面找一把伞. 即遍历前面的每个点j, ...

  2. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  3. CodeForces 988 F Rain and Umbrellas

    Rain and Umbrellas 题意:某同学从x=0的点走到x=a的点,路上有几段路程是下雨的, 如果他需要经过这几段下雨的路程, 需要手上有伞, 每一把伞有一个重量, 求走到重点重量×路程的最 ...

  4. [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)

    [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...

  5. Rain and Umbrellas(dp)

    题目链接 http://codeforces.com/problemset/problem/988/F 令dp[i][j]为走到目标为i处,手里拿着第j把伞,同时注意,在某处可能存在不止一把伞 #in ...

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

    一.题目链接:http://codeforces.com/contest/988/problem/F 二.题面 三.思路 很明显而且比较能想到的$dp$. 四.代码实现 #include<bit ...

  7. codeforces 721C (拓排 + DP)

    题目链接:http://codeforces.com/contest/721/problem/C 题意:从1走到n,问在时间T内最多经过多少个点,按路径顺序输出. 思路:比赛的时候只想到拓排然后就不知 ...

  8. codeforces 711C Coloring Trees(DP)

    题目链接:http://codeforces.com/problemset/problem/711/C O(n^4)的复杂度,以为会超时的 思路:dp[i][j][k]表示第i棵数用颜色k涂完后bea ...

  9. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. 解题:SCOI 2012 喵星球上的点名

    题面 初见广义SAM 建立广义SAM,每次把询问走一遍,最终走到节点的子树里的猫老师都被这次点名点到 这样DFS parent树打时间戳记录入栈出栈时间,把问题转化成一个序列问题:给一个若干种颜色构成 ...

  2. 解题:WC 2006 水管局长

    题面 初见LCT,动态最小生成树+链上查询max,具体做法是把边转换成点(LCT只能维护点) 时光倒流,先把最后剩的连起来.然后查询就看链上最大值,修改看看链上最大值是否大于当前边,如果是就断开原来的 ...

  3. 解题:POI 2008 Station

    题面 水水的换根裸题,不过以前还真没做过换根的题 换根的思想就是在DFS中利用树的信息更新出当前点为根时的信息,具体来说一般是考虑子树外和子树内两部分 每个点的答案$ans$就是$ans[fa]+n- ...

  4. 【线段树合并】【P2824】 [HEOI2016/TJOI2016]排序

    Description 给定一个长度为 \(n\) 的排列,有 \(m\) 次操作,每次选取一段局部进行升序或降序排序,问你一波操作后某个位置上的数字是几 Hint \(1~\leq~n,~m~\le ...

  5. gdb调试4--回退

    加入你正在使用GDB7.0以上版本的调试器并且运行在支持反向调试的平台,你就可以用以下几条命令来调试程序: reverse-continue 反向运行程序知道遇到一个能使程序中断的事件(比如断点,观察 ...

  6. 实验一:使用ADO.NET方式读数据

    第一步:创建Asp.net应用程序 在VS中,点击文件->新建->项目,按如图方式选择并输入: 第二步:新建产品浏览网页窗体Listing.aspx: 在项目SportsStoreEx上点 ...

  7. Zabbix应用一:Zabbix安装

    1.准备zabbix依赖环境:LNMP 依赖包安装参考http://www.osyunwei.com/archives/10057.html. cmake安装mysql: cmake . -DCMAK ...

  8. Ubuntu16.04.2安装Tensorflow

    安装aptitude $ sudo apt-get install aptitude 安装python-pip python-dev $ sudo aptitude install python-pi ...

  9. MySQL数据库远程连接很慢的解决方案

    在开发机器上链接mysql数据库很慢,但是在数据库服务器上直接链接数据库很快.猜测应该是远程链接解析的问题,在查询MySQL相关文档和网络搜索后,发现了一个配置似乎可以解决这样的问题,就是在MySQL ...

  10. 《java语言程序设计》初步学习——各种小Demo

    发现现在的天下几乎都是java的天下啊,虽然我个人对java没什么好感,但是迫于生活压力,还是学一下吧,我关注的应该主要还是web方面,所以应该学的是 java server page(JSP),所以 ...