今年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. js绝对地址图片转换成base64的方法

    //将图片转换成base64 function getBase64Image(url, callback){ var canvas = document.createElement('canvas') ...

  2. 常用curl测试命令

    1.curl 基础用法 2.curl 常用 3.curl 拓展 1.curl基础用法 语法:# curl [option] [url] curl除了用以请求数据,还可以用来上传下载 -A/--user ...

  3. Gradle依赖的统一管理,解决依赖冲突

    看见别人在用implementation rootProject.ext.dependencies["xxxx"]不知道是什么意思,上网查了一下,原来是为了解决或者说预防gradl ...

  4. mycat 9066管理端口

    1.连接mycat 9066管理端口 命令:mysql -uroot -proot -P9066 -h127.0.0.1 -u:用户名 -p:密码 -P:端口 -h:ip地址例:linux路径切换到m ...

  5. 设置gem源,解决下载慢的问题

    问题解决的最好方法方法 使用google的DNS 8.8.8.8 / 8.8.4.4 另一种解决方式 修改rubygems的source源 $ gem source -r http://rubygem ...

  6. Python简易web服务

    利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录的路径下,输入命令: python -m Web服务器模块 [端口号,默认8000] 例如: python -m ...

  7. Linux日常使用命令

    pwd  当前目录的路径ls -a 显示隐藏文件ls -l h*  显示所有以h开头的文件ls -d  b*  显示所有以b开头的文件夹ls -l  *.log  所有后缀是.log 的文件dir 显 ...

  8. How to hard reset Visual Studio instance

    When developing extensions sometimes you just mess up, others someone else does. If you start gettin ...

  9. OpenGL——三维多面体实现

    #include<iostream> #include <math.h> #include<Windows.h> #include <GL/glut.h> ...

  10. Maven传递依赖的坑:父pom中dependencyManagement版本优先级高于传递依赖版本

    一.由来 之前同事问了个问题,就是当前工程为spring boot项目,假设版本号为2.0.3 这个项目中依赖了一个spring boot项目依赖(先别管为啥有这么奇葩的依赖,这个版本是1.5.9). ...