【Codeforces559E】Gerald and Path
来源:互联网 发布:mysql官网下载 编辑:程序博客网 时间:2024/06/16 09:01
题意:
- 一条路上有
n 盏不同的灯,每盏灯所在位置为pi ,向左或者向右可以照射的距离为li ,求最大总照射长度。 n≤100,li,pi≤108 。
题解:
- 这道题dp思路似乎都很神奇?
- 设
dp[i][j][k] 表示到第i 盏灯(按位置从左到右),最左边的需要覆盖到的位置是j (0代表不存在未覆盖),最右端位置是k ,包括了这段实际没有覆盖的最大总长度。 - 考虑转移:
- 向右照射,且之前的最左边需要覆盖的位置不变,转移方程:
dp[i][j][max(R[i],k)]=max(dp[i][j][max(R[i],k)],dp[i−1][j][k]+max(0,R[i]−k]))
- 向左照射,且覆盖掉了原来实际没有覆盖(或者原来没有未覆盖)的部分,转移方程:
dp[i][0][max(p[i],k)]=max(dp[i][0][max(p[i],k)],dp[i−1][j][k]+max(0,p[i]−k]))(L[i]≤j)
- 向右照射,且原来没有未覆盖部分,最右边位置在当前灯位置左边,取最右边位置后某一处
j 到当前位置作为假装覆盖实际没有覆盖部分(或者不选取),转移方程:dp[i][k][R[i]]=max(dp[i][k][R[i]],dp[i−1][0][j]+R[i]−k)(j≤k<p[i])
- 向左照射,且原来没有未覆盖部分,最右边位置在当前灯照射左边界左边,取最右边位置后某一处
j 到当前位置作为假装覆盖实际没有覆盖部分(或者不选取),转移方程:dp[i][k][max(x[i],j)]=max(dp[i][k][max(x[i],j)],dp[i−1][0][j]+p[i]−k)(j≤k<L[i])
- 向右照射,且之前的最左边需要覆盖的位置不变,转移方程:
- 总时间复杂度
O(n3) 。
代码:
#include <bits/stdc++.h>#define gc getchar()#define N 109using namespace std;int n,x[N],l[N],num[N],L[N],R[N],a[N],b[N],dp[N][N*3][N*3],ans;vector <int> lsh;int read(){ int x=1; char ch; while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1; int s=ch-'0'; while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-48; return s*x;}bool cmp(int aa,int bb){ return x[aa]<x[bb];}int main(){ n=read(); for (int i=1;i<=n;i++) { x[i]=read(),l[i]=read(),num[i]=i; lsh.push_back(x[i]-l[i]),lsh.push_back(x[i]),lsh.push_back(x[i]+l[i]); } sort(num+1,num+n+1,cmp); sort(lsh.begin(),lsh.end()); lsh.erase(unique(lsh.begin(),lsh.end()),lsh.end()); for (int i=1;i<=n;i++) a[i]=x[num[i]],b[i]=l[num[i]]; for (int i=1;i<=n;i++) { L[i]=lower_bound(lsh.begin(),lsh.end(),a[i]-b[i])-lsh.begin()+1; x[i]=lower_bound(lsh.begin(),lsh.end(),a[i])-lsh.begin()+1; R[i]=lower_bound(lsh.begin(),lsh.end(),a[i]+b[i])-lsh.begin()+1; } for (int i=1;i<=n;i++) { for (int j=1;j<=lsh.size();j++) for (int k=j;k<=lsh.size();k++) { dp[i][j][max(R[i],k)]=max(dp[i][j][max(R[i],k)],dp[i-1][j][k]+max(0,lsh[R[i]-1]-lsh[k-1])); if (L[i]<=j) dp[i][0][max(x[i],k)]=max(dp[i][0][max(x[i],k)],dp[i-1][j][k]+max(0,lsh[x[i]-1]-lsh[k-1])); } for (int j=1;j<=lsh.size();j++) { if (j<x[i]) { dp[i][0][R[i]]=max(dp[i][0][R[i]],dp[i-1][0][j]+lsh[R[i]-1]-lsh[x[i]-1]); for (int k=j;k<x[i];k++) dp[i][k][R[i]]=max(dp[i][k][R[i]],dp[i-1][0][j]+lsh[R[i]-1]-lsh[k-1]); } else dp[i][0][max(R[i],j)]=max(dp[i][0][max(R[i],j)],dp[i-1][0][j]+max(0,lsh[R[i]-1]-lsh[j-1])); dp[i][0][max(x[i],j)]=max(dp[i][0][max(x[i],j)],dp[i-1][0][j]+max(0,lsh[x[i]-1]-lsh[max(j,L[i])-1])); for (int k=j;k<L[i];k++) dp[i][k][max(x[i],j)]=max(dp[i][k][max(x[i],j)],dp[i-1][0][j]+lsh[x[i]-1]-lsh[k-1]); } } for (int i=1;i<=lsh.size();i++) ans=max(ans,dp[n][0][i]); printf("%d\n",ans); return 0;}
阅读全文
0 0
- 【Codeforces559E】Gerald and Path
- codeforces 559E Gerald and Path
- codeforces 559E Gerald and Path
- Codeforces Round #313 (Div. 1) E. Gerald and Path dp 记忆化搜索 stl应用
- Gerald and Giant Chess (CodeForces
- codeforce 559 C Gerald and Giant Chess
- 【数论+dp】codeforces559C Gerald and Giant Chess
- Codeforces 560E Gerald and Giant Chess
- codeforces 559C Gerald and Giant Chess
- Codeforces 664A Gerald and Giant Chess
- codeforces(559C)--C. Gerald and Giant Chess(组合数学)
- codeforces 559C Gerald and Giant Chess(dp+组合数学)
- codeforces 559C Gerald and Giant Chess(组合数学)
- Codeforces 559C Gerald and Giant Chess 组合数学 DP
- Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess
- Codeforces Round #313(div.2) E. Gerald and Giant Chess
- CF#313-E. Gerald and Giant Chess-dp+组合数学
- Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess
- Hbase-API-概述、单多行put
- springboot启动与调用
- <object>元素通过js设置宽高
- 理解RemoteViews概念
- 搭建数据仓库第02篇:数据仓库技术架构解决方案
- 【Codeforces559E】Gerald and Path
- JSON对象字符串数组多字段(多列)排序
- 嵌套 Tab 时部分 Fragment 不显示及指示器 Indicator 卡顿问题
- 小结六
- [WQS二分] BZOJ2654:tree
- 【接口报错】写接口,返回json给ajax时,一直是error函数接收。
- Linux指令用之记之-tr
- word-wrap和word-break区别详解
- lambda表达式