今年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. java解析Excel(xls、xlsx两种格式)

    https://www.cnblogs.com/hhhshct/p/7255915.html ***************************************************** ...

  2. VIM空格和TAB转换

    在.vimrc中添加以下代码后,重启vim即可实现按TAB产生4个空格:set ts=4 (注:ts是tabstop的缩写,设TAB宽4个空格)set expandtab 对于已保存的文件,可以使用下 ...

  3. 模仿CountDownLatch类自定义倒时计时器

    简介 这里模仿CountDownLatch类自定义到时计时器,利用AQS模板中的尝试获得共享和释放共享 1.MyCountDownLatch package com.jacky; import com ...

  4. 利用堆实现堆排序&amp;优先队列

    数据结构之(二叉)堆一文在末尾提到"利用堆能够实现:堆排序.优先队列.".本文代码实现之. 1.堆排序 如果要实现非递减排序.则须要用要大顶堆. 此处设计到三个大顶堆的操作:(1) ...

  5. 【iCore1S 双核心板_FPGA】例程七:基础逻辑门实验——逻辑门使用

    实验现象: 打开tool-->Netlist viewer-->RTL viewer可观察各个逻辑连接 核心代码: //-----------------Module_logic_gate ...

  6. WebRTC 零基础开发者教程(中文版)下载

    WebRTC 简介 WebRTC,是一个支持网页浏览器进行实时语音通话或视频聊天的技术,是谷歌2010年以6820万美元收购Global IP Solutions公司而获得的一项技术. WebRTC提 ...

  7. 关于CLOS架构的举例 网络级 设备级 FATTREE网络 网络级CLOS 以及CLOS涉及的调度算法RR

    1.概述 CLOS来自于传统电路交换概念,这个概念年代太久远,在当前数据通信网络中,内涵有所变化.本文主要谈的是实际上赋予的与原来略微有所差异的内涵. CLOS架构本身概念比较宽泛,有设备级的CLOS ...

  8. 【转】搭建Java版WebService

    原文地址:http://www.cnblogs.com/jasoncc/archive/2011/12/22/2296052.html Hi,大家好! 今天主要和大家分享,如何搭建一个Web服务,做A ...

  9. SpringBoot切换Tomcat容器,SpringBoot使用Jetty容器

    SpringBoot切换Tomcat容器, SpringBoot修改为Jetty容器, SpringBoot使用undertow容器, SpringBoot使用Jetty容器 ============ ...

  10. Markdown 表格

    表格的基本写法很简单,就跟表格的形状很相似,冒号在左边表示左对齐,右边表示右对齐,两边都有表示居中,如果都不写冒号则默认左对齐 学号|姓名|分数 :-|:-:|-: 小明|男|75 小红|女|79 小 ...