sol:第一题就DP?!然后写了O(n^2) dp再考虑优化!!!(尽量部分分带上!!!)

我写了正确的dp然后优化错了,具体的dp方法是考虑到对于右侧到左侧他是没有后效性的

所以定义f[i]为i及以后最大的代价和,对于合法的j,转移f[i]=max{f[j]+P[i]},j需要满足a[i]+x[i]<a[j],j>=i

由于给出的a[i]递增然后我只要往i的右侧找到第一个合法的j然后转移就行了,复杂度O(n log n)

我错在了用堆来优化,然后把后面的删掉了,其实可以再前面的从被误删的东西转移而来。

code:

# include <bits/stdc++.h>
# ifdef O_2
# pragma GCC optimze()
# endif
# define int long long
using namespace std;
const int MAXN=1e5+;
int f[MAXN],a[MAXN],x[MAXN],p[MAXN];
int n;
inline int read()
{
int X=,w=;char c=;
while (!(c>=''&&c<='')) w|=c=='-',c=getchar();
while (c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
inline void write(int x)
{
if (x<) { x=-x;putchar('-');}
if (x>) write(x/);
putchar(''+x%);
}
inline void writeln(int x) { write(x);putchar('\n');}
signed main()
{
n=read();
for (int i=;i<=n;i++)
a[i]=read(),p[i]=read(),x[i]=read();
f[n]=p[n];
for (int i=n-;i>=;i--) {
f[i]=f[i+];
int j=upper_bound(a+i+,a++n,a[i]+x[i])-a;
f[i]=max(max(f[i],p[i]),f[j]+p[i]);
}
writeln(f[]);
return ;
}

sol:这道题目对于100%的数据n,m<=3000,显然发现这一定是O(n2)的算法,

然后如果对于X1到X2的最短路径设为R1,X3到X4最短路劲R2,要求R1和R2交的尽可能多,那么这个解一定更优

首先一定要在最短路上,其次要求R1和R2尽可能交的更多,我们不妨设刚开始交的地方设为i,交结束的地方设为j

我们先求出X1,X2,X3,X4到各点的最短路D1,D2,D3,D4

我们枚举i然后再枚举j 由上图可以看出就是D1[i]+D2[j]+D3[i]+D4[j]+dist(i,j)在枚举j之前我们可以O(n)求出i的最短路D5

那么就是最小化D1[i]+D2[j]+D3[i]+D4[j]+D5[j],

然后我们交换(X1,X2)or (X3,X4) 之中的任意一对然后再求min,就是D1[i]+D2[j]+D3[j]+D4[i]+D5[j],

然后对于每一次枚举Ans=Min(D1[i]+D2[j]+D3[i]+D4[j]+D5[j],D1[i]+D2[j]+D3[j]+D4[i]+D5[j],ans)

对于一个显然的情况我们最后特判就是直接 X1走到X2,X3 走到 X4 最短路虽然并没有重复的路 即 ans=Min(ans,D1[X2]+D3[X4]);

code:

# include <bits/stdc++.h>
# ifdef O_2
# pragma GCC optimze()
# endif
using namespace std;
const int MAXN=;
int n,m,X1,X2,X3,X4;
int D1[MAXN],D2[MAXN],D3[MAXN],D4[MAXN],D5[MAXN];
int tot=,head[MAXN];
bool vis[MAXN];
struct rec{ int pre,to,w;}a[MAXN*];
inline int read()
{
int X=,w=;char c=;
while (!(c>=''&&c<='')) w|=c=='-',c=getchar();
while (c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
inline void write(int x)
{
if (x<) { x=-x;putchar('-');}
if (x>) write(x/);
putchar(''+x%);
}
inline void writeln(int x) { write(x);putchar('\n');}
void adde(int u,int v,int w)
{
a[++tot].pre=head[u];
a[tot].to=v;
a[tot].w=w;
head[u]=tot;
}
struct node{ int id,dist;};
int d[MAXN];
queue<node>q;
void bfs(int s)
{
memset(vis,false,sizeof(vis));
memset(d,0x3f,sizeof(d));
d[s]=; vis[s]=;
q.push((node){s,});
while (!q.empty()) {
node u=q.front();q.pop();
for (int i=head[u.id];i;i=a[i].pre) {
int v=a[i].to;
if (vis[v]) continue;
vis[v]=;
d[v]=u.dist+;
q.push((node){v,d[v]});
}
}
}
int Min(int a,int b,int c)
{
if (b<a) a=b;
if (c<a) a=c;
return a;
}
int main()
{
n=read();m=read();
X1=read();X2=read();X3=read();X4=read();
int u,v;
for (int i=;i<=m;i++) {
u=read();v=read();
adde(u,v,); adde(v,u,);
}
bfs(X1); memcpy(D1,d,sizeof(d));
bfs(X2); memcpy(D2,d,sizeof(d));
bfs(X3); memcpy(D3,d,sizeof(d));
bfs(X4); memcpy(D4,d,sizeof(d));
int ans=m;
for (int i=;i<=n;i++) {
bfs(i); memcpy(D5,d,sizeof(d));
for (int j=;j<=n;j++)
ans=Min(ans,D1[i]+D3[i]+D2[j]+D4[j]+D5[j],D1[i]+D4[i]+D3[j]+D2[j]+D5[j]);
}
ans=min(ans,D1[X2]+D3[X4]);
writeln(ans);
return ;
}

HGOI20181031 模拟题解的更多相关文章

  1. HGOI20181029模拟题解

    HGOI20181029模拟题解 /* sxn让我一定要谴责一下出题人和他的数据! */ problem: 给出十进制数a,b,然后令(R)10=(a)10*(b)10,给出c表示一个k进制数(1&l ...

  2. 【 P3952】 时间复杂度 大模拟题解

    题目链接 完全模拟 1.模拟结果 当我们的模拟程序执行结束时,直接执行模拟结果函数,用于比对我们的结果和数据给出的结果. bool yes(char a[],char b[]) { ;i<=;+ ...

  3. HGOI20181030 模拟题解

    problem:给定一个序列,问你能不能通过一次交换把他弄成有序 sol: 对于0%的数据,满足数列是一个排列,然后我就打了这档分(自己瞎造的!) 对于100%的数据,显然我们先对数列进行排序然后上下 ...

  4. CSYZDay2模拟题解

    T1.rotate [问题描述] ZYL有N张牌编号分别为1, 2,……,N.他把这N张牌打乱排成一排,然后他要做一次旋转使得旋转后固定点尽可能多.如果第i个位置的牌的编号为i,我们就称之为固定点.旋 ...

  5. CSYZDay1模拟题解

    T1.game [问题描述] LZK发明一个矩阵游戏,大家一起来玩玩吧,有一个N行M列的矩阵.第一行的数字是1,2,…M,第二行的数字是M+1,M+2…2*M,以此类推,第N行的数字是(N-1)*M+ ...

  6. 2019-06-03 校内python模拟题解(所有非原题)

    一起来女装吧 本题改编自USACO(USA Computing Olympiad) 1.1节的第一题 (感谢lsy同学对本题题面的贡献) 直接计算就好了 chr:将ASCII码转成字符 ord:字符对 ...

  7. ZOJ Monthly, June 2014 月赛BCDEFGH题题解

    比赛链接:点击打开链接 上来先搞了f.c,,然后发现状态不正确,一下午都是脑洞大开,, 无脑wa,无脑ce...一样的错犯2次.. 硬着头皮搞了几发,最后20分钟码了一下G,不知道为什么把1直接当成不 ...

  8. hdu_5818_Joint Stacks(线段树模拟)

    题目链接:hdu_5818_Joint Stacks 题意: 给你两个栈,多了个合并操作,然后让你模拟 题解: 很容易想到O(1)的单个栈操作,O(n)的合并操作,这样肯定超时,所以我们要将时间复杂度 ...

  9. CSU 1862 The Same Game(模拟)

    The Same Game [题目链接]The Same Game [题目类型]模拟 &题解: 写这种模拟题要看心态啊,还要有足够的时间,必须仔细读题,一定要写一步,就调试一步. 这题我没想到 ...

随机推荐

  1. 2017-2018-2 《网络对抗技术》20155322 Exp9 web安全基础

    [-= 博客目录 =-] 1-实践目标 1.1-实践介绍 1.2-实践内容 1.3-实践要求 2-实践过程 2.1-HTML 2.2-Injection Flaws 2.3-XSS 2.4-CSRF ...

  2. Python+Selenium爬取动态加载页面(2)

    注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...

  3. 蓝牙重启case之:hardware error

    蓝牙的通信分为host和controller,host端发送数据和命令到controller,controller 上传event以及数据到host端,这要求上下两端的通信要求状态一致性. 当发生状态 ...

  4. cocos2d-x学习记录3——CCTouch触摸响应

    游戏不同于影音,强交互性是其一大特色,在游戏中主要体现为接受用户的输入并响应.智能手机触摸是其重要的输入方式. 在cocos2d-x中,触摸分为单点触摸和多点触摸. 单点触摸:主要继承CCTarget ...

  5. [CF966F]May Holidays[分块+虚树]

    题意 给定 \(n\) 个点的树,初始所有颜色都是 \(0\) ,每个点有一个阈值 \(t\) ,每次可能会让一个点的颜色异或1,问每次操作之后有多少个点满足子树内的颜色为 \(1\) 的点的个数 \ ...

  6. [51Nod1238]最小公倍数之和 V3[杜教筛]

    题意 给定 \(n\) ,求 \(\sum_{i=1}^n \sum_{j=1}^n lcm(i,j)\). \(n\leq 10^{10}\) 分析 推式子 \[\begin{aligned} an ...

  7. sql优化详细介绍学习笔记

    因为最近在面试,发现sql优化这个方面问的特别特别的多.之前都是零零星星,不够全面的了解一点,刚刚在网上查了一下,从 http://blog.csdn.net/zhushuai1221/article ...

  8. 架构师修炼 II - 表达思维与驾驭方法论

    开篇之前我想先说说当年开发的那点事儿:大约10年前吧,我还是一个程序员的时候经常都是遇到这样的项目开发流程: 解决方案 :满足客户目的和投标用的一堆文档(不少还是互联网上抄的) ,是以Word为主的纯 ...

  9. OpenGL:使用顶点数组法绘制正六面体

    在今天的opengl的课程以及实验中,我们学习了如何使用顶点数组的方法来绘制图形,但相信还有很多同学对它的实际使用方法不太了解,我们就用我们今天实验课上的实例来简单讲解一下 题目及要求 绘制一个正六面 ...

  10. [转载]JAVA内存分析——栈、堆、方法区 程序执行变化过程

    面向对象的内存分析 参考:http://www.sxt.cn/Java_jQuery_in_action/object-oriented.html :尚学堂JAVA300集-064内存分析详解_栈_堆 ...