今年noip的题和去年绝对是比较坑的题了,但是打好的话就算是普通水准也能350分以上吧。

t1:

很显然这是一个简单的dp即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<ctime>
#include<iomanip>
#include<vector>
#include<map>
#include<queue>
#include<stack>
using namespace std;
inline long long read()
{
long long x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const long long maxn=;
long long n;
long long a[maxn],now=,ans=;
int main()
{
//freopen("road.in","r",stdin);
//freopen("road.out","w",stdout);
n=read();
for(long long i=;i<=n;i++)a[i]=read();
for(long long i=;i<=n;i++)
{
if(a[i]>now){ans+=a[i]-now;now=a[i];}
else now=a[i];
}
printf("%lld\n",ans);
return ;
}

t2:

很显然,这是个完全背包,考试的时候沙比没看出来打了搜索。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<ctime>
#include<iomanip>
#include<vector>
#include<map>
#include<queue>
#include<stack>
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int maxn=;
int t,n;
int a[maxn],f[],ans=;
int main()
{
//freopen("1.in","r",stdin);
//freopen("money.out","w",stdout);
t=read();
for(int u=;u<=t;u++)
{
memset(f,,sizeof(f));
n=read();f[]=;ans=;
for(int i=;i<=n;i++)a[i]=read();
for(int i=;i<=n;i++)
for(int j=a[i];j<=;j++)
f[j]+=f[j-a[i]];
for(int i=;i<=n;i++)if(f[a[i]]==)ans++;
printf("%d\n",ans);
}
return ;
}

暴力55分代码如下:

#include<bits/stdc++.h>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<queue>
#include<deque>
#include<bitset>
#include<set>
#include<vector>
#include<algorithm>
#include<stack>
#include<map>
#include<iomanip>
using namespace std;
inline long long read()
{
long long x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void put(long long x)
{
if(x==){putchar('');putchar('\n');return;}
if(x<)putchar('-'),x=-x;
long long num=;char ch[];
while(x)ch[++num]=x%+'',x/=;
while(num)putchar(ch[num--]);
putchar('\n');return;
}
const long long maxn=;
long long n,m,flag=,flag1=;
long long lin[maxn<<],nex[maxn<<],ver[maxn<<],e[maxn<<],len=;
long long ru[maxn],s,ans=,q[maxn<<],h=,t=,vis[maxn<<];
long long d[maxn],cnt=,u;
void add(long long x,long long y,long long z)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
e[len]=z;
}
//赛道修建 55分做法
long long check1(long long x)
{
t=;h=;
long long tot=,num=;
q[++t]=s;
memset(vis,,sizeof(vis));
vis[s]=;
//cout<<x<<endl;
while(h++<t)
{
long long te=q[h];
for(long long i=lin[te];i;i=nex[i])
{
long long tn=ver[i];
if(vis[tn]==)continue;
q[++t]=tn;
num+=e[i];
vis[tn]=;
if(num>=x)tot++,num=;
}
}
if(tot>=m)return ;
else return ;
}
void solve1()//一条链
{
for(long long i=;i<=n;i++)if(ru[i]==){s=i;break;}
//cout<<s<<endl;
//cout<<m<<endl;
//cout<<ans<<endl;
long long l=,r=ans;
while(l+<r)
{
long long mid=(l+r)>>;
if(check1(mid)==)l=mid;
else r=mid;
}
if(check1(r)==)put(r);
else put(l);
return;
}
void dp(long long x)
{
vis[x]=;
for(long long i=lin[x];i;i=nex[i])
{
long long tn=ver[i];
if(vis[tn]==)continue;
dp(tn);
cnt=max(cnt,d[x]+d[tn]+e[i]);
d[x]=max(d[x],d[tn]+e[i]);
}
return;
}
void bfs()
{
h=,t=;cnt=;
memset(vis,,sizeof(vis));
memset(d,,sizeof(d));
q[++t]=;vis[]=;
while(h++<t)
{
long long te=q[h];
for(long long i=lin[te];i;i=nex[i])
{
long long tn=ver[i];
if(vis[tn]==)continue;
d[tn]=max(d[tn],d[te]+e[i]);//取max更加严谨,尽管更慢
if(d[tn]>cnt)cnt=d[tn],u=tn;
q[++t]=tn;vis[tn]=;
}
}
//cout<<u<<endl;
memset(vis,,sizeof(vis));
memset(d,,sizeof(d));
h=,t=;cnt=;
q[++t]=u;vis[u]=;
//cout<<u<<endl;
while(h++<t)
{
long long te=q[h];
for(long long i=lin[te];i;i=nex[i])
{
long long tn=ver[i];
if(vis[tn]==)continue;
d[tn]=max(d[tn],d[te]+e[i]);//取max更加严谨,尽管更慢
if(d[tn]>cnt)cnt=d[tn];
q[++t]=tn;vis[tn]=;
}
}
put(cnt);return;
}
void dfs(int x)
{
for(int i=lin[x];i;i=nex[i])
{
int tn=ver[i];
if(vis[tn]==)continue;
vis[tn]=;
d[tn]=max(d[tn],d[x]+e[i]);
if(d[tn]>cnt)cnt=d[tn],u=tn;
dfs(tn);
}
}
int check2(int x)
{
cnt=;int j=t+;//双指针
for(int i=;i<=t;i++)if(q[i]>=x){j=i;break;}
cnt+=t-j+;j--;
for(int i=;i<j;i++)if(q[i]+q[j]>=x)j--,cnt++;
if(cnt>=m)return ;
return ;
}
void solve2()//菊花图
{
h=,t=;
for(int i=lin[];i;i=nex[i])q[++t]=e[i];
sort(q+,q++t);
//cout<<ans<<endl;
//for(int i=1;i<=t;i++)cout<<q[i]<<endl;
int l=,r=ans;
while(l+<r)
{
int mid=(l+r)>>;
if(check2(mid)==)l=mid;
else r=mid;
}
if(check2(r)==)put(r);
else put(l);return;
}
void solve3()
{
memset(vis,,sizeof(vis));
memset(d,,sizeof(d));
dp();put(cnt);//树形dp求树的直径
//bfs();//两次bfs求树的直径
//两次dfs求树的直径
/*memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
cnt=0;vis[1]=1;dfs(1);
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
cnt=0;vis[u]=1;dfs(u);
put(cnt);*/
}
int main()
{
//freopen("1.in","r",stdin);
n=read();m=read();
for(long long i=;i<n;i++)
{
long long x,y,z;
x=read();y=read();z=read();
add(x,y,z);add(y,x,z);
if(x+!=y)flag=;//一条链的情况
ru[x]++;ru[y]++;
ans+=z;
if(x!=)flag1=;
}
//cout<<flag1<<endl;
if(flag==){solve1();return ;}//一条链
if(flag1==){solve2();return ;}//菊花图
if(m==){solve3();return ;}//求树的直径的情况,两遍bfs或树形dp
return ;
}

55分很好写,一个直径一个二分一个双指针扫描。

可是考试的时候打了一个n^n的暴力。菜死了

正解是二分+树形dp+二分(二分的边界很重要要不卡死)

#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<queue>
#include<deque>
#include<bitset>
#include<set>
#include<vector>
#include<algorithm>
#include<stack>
#include<map>
#include<iomanip>
using namespace std;
inline long long read()
{
long long x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void put(long long x)
{
if(x==){putchar('');putchar('\n');return;}
if(x<)putchar('-'),x=-x;
long long num=;char ch[];
while(x)ch[++num]=x%+'',x/=;
while(num)putchar(ch[num--]);
putchar('\n');return;
}
const long long maxn=;
long long n,m;
long long lin[maxn<<],nex[maxn<<],ver[maxn<<],e[maxn<<],len=;
int ans=,u=,cnt=;
int f[maxn],v[maxn];//f[i]表示以i为根节点所能拼成最多的道路。
int q[maxn<<],t=;
//v[i]表示当前节点还剩下的最长链
void add(long long x,long long y,long long z)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
e[len]=z;
}
//赛道修建100分做法-->>树形dp
int check1(int x,int p)
{
int sum=;
for(int i=,j=t;i<j;i++)
{
if(i==x)continue;
if(j==x)j--;
if(q[i]+q[j]>=p)sum++,j--;
}
if(sum>=u)return ;
return ;
}
void dp(int x,int p,int fa)
{
for(int i=lin[x];i;i=nex[i])
{
int tn=ver[i];
if(tn==fa)continue;
dp(tn,p,x);
}
t=,u=;;cnt=;
for(int i=lin[x];i;i=nex[i])
{
int tn=ver[i];
if(tn==fa)continue;
f[x]+=f[tn];
if(e[i]+v[tn]>=p){cnt++;continue;}
q[++t]=e[i]+v[tn];
}
sort(q+,q++t);
for(int i=,j=t;i<j;i++)if(q[i]+q[j]>=p)u++,j--;
int l=,r=t;//再次二分枚举哪条边不用来更新v[x]
while(l+<r)
{
int mid=(l+r)>>;
if(check1(mid,p)==)l=mid;
else r=mid;
}
if(check1(r,p)==)v[x]=q[r];
else v[x]=q[l];
f[x]+=cnt+u;
}
int check(int x)
{
memset(f,,sizeof(f));
memset(v,,sizeof(v));
dp(,x,);
if(f[]>=m)return ;
else return ;
}
void wy()//闻道玉门犹被遮
{
int l=,r=ans;
while(l+<r)//二分枚举当前修建的道路长度
{
int mid=(l+r)>>;
if(check(mid)==)l=mid;
else r=mid;
}
if(check(r)==)put(r);
else put(l);
}
int main()
{
//freopen("1.in","r",stdin);
n=read();m=read();
for(int i=;i<n;i++)
{
int x,y,z;
x=read();y=read();z=read();
add(x,y,z);add(y,x,z);
ans+=z;
}
wy();//应将性命逐轻车
return ;
}

就这样没了 300分很简单。

NOIP 2018 day1 题解的更多相关文章

  1. [NOIP 2018 Day1] 简要题解

    [题目链接] 铺设道路 : https://www.luogu.org/problemnew/show/P5019 货币系统 : https://www.luogu.org/problemnew/sh ...

  2. Noip 2016 Day1 题解

    老师让我们刷历年真题, 然后漫不经心的说了一句:“你们就先做做noip2016 day1 吧” ...... 我还能说什么,,,,,老师你这是明摆着伤害我们啊2333333333 预计分数:100+2 ...

  3. NOIP 2018 Day1

    Fei2Xue@Lian$Tian! 三道原题qwq真的凉 半年前看到有人发说说,梦见省选打开题目,是Please contact lydsy2012@163.com! 没想到一语成谶 大众分300 ...

  4. NOIP 2018 简要题解

    从这里开始 Day 1 Problem A 考虑贪心地选取极大非 0 段减少. 如果两次操作有交,并且不是包含关系,那么把其中一次操作的,但另一次没有操作的移过去,然后就变成了上面那个贪心了. Cod ...

  5. noip 2018 day1 T2 货币系统 完全背包

    Code: #include<cstdio> #include<string> #include<cstring> #include<algorithm> ...

  6. noip 2018 day1 T3 赛道修建 贪心_树上问题_multiset

    Code: // luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; #define maxn 5000 ...

  7. noip 2018 day1 T1 铺设道路 贪心

    Code: #include<cstdio> using namespace std; int main() { int last=0,ans=0; int n;scanf("% ...

  8. NOIP 2018旅行题解

    从佳木斯回来刷一刷去年没A的题 题目描述 小 Y 是一个爱好旅行的 OIer.她来到 X 国,打算将各个城市都玩一遍. 小Y了解到, X国的 nn 个城市之间有 mm 条双向道路.每条双向道路连接两个 ...

  9. noip 2018 d2t1 旅行

    noip 2018 d2t1 旅行 (题目来自洛谷) 给定n个城市,m条双向道路的图, 不存在两条连接同一对城市的道路,也不存在一条连接一个城市和它本身的道路.并且, 从任意一个城市出发,通过这些道路 ...

随机推荐

  1. IIS发布的网站常见的问题汇总

    1.安装.NET4.0时缺少WIC导致不能装上.NET4.0,下载安装后即可,下载地址如下,根据系统版本选择对应软件 32位版:https://www.microsoft.com/zh-cn/down ...

  2. golang:mime.Encode、mime.Decode

    最近在做邮件解析的工作,所以记录一下对mime.Encode.mime.Decode的总结.

  3. cocos2d-x 重力感应

    本文没你想象的那么,,复杂.事实上就是通过重力感应控制个小球移动而已. 先看头文件: #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE ...

  4. 【原】在Matplotlib绘图中添加Latex风格公式

    Matplotlib绘图的过程中,可以为各个轴的Label,图像的Title.Legend等元素添加Latex风格的公式. 只需要在Latex公式的文本前后各增加一个$符号,Matplotlib就可以 ...

  5. altium designer 10如何画4层板

    本篇博客主要讲解一下如何用altium designer10去画4层板. 想想当初自己画4层板时,也去网上海找资料,结果是零零散散,也没讲出个123,于是硬着头皮去找师兄,如何画4层板.师兄冷笑道:“ ...

  6. Docker GitLab镜像部署

    环境说明 系统环境: CentOS Linux release 7.4 docker Version: 18.03.1-ce 运行镜像 docker run --detach \ --hostname ...

  7. Spark搭建HA具体解释

    实验环境: zookeeper-3.4.6 Spark:1.6.0 简单介绍: 本篇博客将从下面几点组织文章: 一:Spark 构建高可用HA架构 二:动手实战构建高可用HA 三:提交程序測试HA 一 ...

  8. linux中free命令内存分析

    Mem(物理内存分配情况)行 total:表示物理 内存总量 used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用 free:未被分配的内存 s ...

  9. 《转载》python爬虫实践之模拟登录

    有些网站设置了权限,只有在登录了之后才能爬取网站的内容,如何模拟登录,目前的方法主要是利用浏览器cookie模拟登录.   浏览器访问服务器的过程   在用户访问网页时,不论是通过URL输入域名或IP ...

  10. [转]pycharm active code

    43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiI ...