【NOIP2016】Day1
来源:互联网 发布:网络吃鸡是什么意思啊 编辑:程序博客网 时间:2024/06/01 23:05
Solution
T1
模拟,可以用异或简化代码
T2
这里讲一下正解,网上题解也有很多
我们把路径插成,u->lca , lca->v,
我们先看u->lca这一条,若这条路径上的点x能观察到u,那么:
移项后得:
发现右边是一个之与x有关的项,我们的目标就是求x的子树中有几个起点u,终点在x以上(含x),且deep[u]=deep[x]+T[x]
这句话让我们想到了什么?树上差分!
我们在u上+1,fa[lca]上-1,就表示了一条链,但这个值怎么搞?开一个桶就行了!
我们对每一个节点建一个类似边表的东西,表示会对那些节点+-1,也可以用vector,然后dfs到u时,遍历一遍这个边表,把他的影响算上,然后+a[T[u]+deep[u]],a是桶。
注意:一个节点可以有多个儿子,但每个儿子只能计数自己的子树内的个数,这样会多次计数,我们可以在进入这个节点前减去答案,最后再加答案,就是加差值,这很重要,也简化了步骤。
往上走也是一样,
移项后:
T3
这道题目赛场上写了一个本来能拿80的错误的DP,但是最短路打错了,只剩20.
对于这个期望有两种理解:一种是每条可能路径的长度*概率,
另外一种是:每两节课之间的每条路的长度*概率,
第二种理解的转化是解题的关键,因为这道题目只有相邻的点会影响路径的选择,所以我们要记录前一节课是在哪里上的,或者说是否申请,
http://www.cnblogs.com/ljh2000-jump/p/6189054.html 此人博客暴力写的都很详细
这显然是一道概率DP裸题。考虑f[i][j][0、1]表示前i堂课,已经申请了j次,这次申不申请的最小期望值
d1=dis[c[i-1]][c[i]],d2=dis[c[i-1]][d[i]],d3=dis[d[i-1]][c[i]],d4=dis[d[i-1]][d[i]];
f[i][j][0]=max{f[i-1][j][0]+d1,f[i-1][j][1]+d3*k[i-1]+d1*(1-k[i-1])}
表示i节课不申请,有两种来源:i-1节课不申请,只可用从c[i-1]走到c[i],i-1节课申请,分类,成功,概率k[i-1],价值d1*k[i-1],失败,概率(1-k[i]),价值d3 *(1-k[i-1]),其他同理。
CODE
T1
#include<bits/stdc++.h>using namespace std;const int MAXN=100000+10;int d[MAXN],n,m;char name[MAXN][15];int main(){ scanf("%d%d",&n,&m); for (int i=0;i<n;i++) scanf("%d%s",&d[i],&name[i]); int now=0,x,y; for (int i=0;i<m;i++) { scanf("%d%d",&x,&y); if (d[now]^x) now=(now+y)%n; else now=(now-y+n)%n; } puts(name[now]); return 0;}
T2
#include<bits/stdc++.h>using namespace std;const int MAXN=300010;int Head[MAXN],Headq[MAXN],Headup[MAXN],Headdown[MAXN];int ans[MAXN],father[MAXN],deep[MAXN],a[MAXN],b[MAXN*2];int s[MAXN],t[MAXN],lca[MAXN],T[MAXN],fa[MAXN];int n,m,tot,tot1;bool vis[MAXN];struct Edge{ int v,next,x;}edge[MAXN*2];struct Ques{ int v,next,id;}que[MAXN*2];struct node{ int next,x,y;}up[MAXN*2],down[MAXN*2];void adde(int x,int y){ edge[++tot]=(Edge){y,Head[x],0}; Head[x]=tot;}void addq(int x,int y,int id){ que[++tot]=(Ques){y,Headq[x],id}; Headq[x]=tot;}void addup(int u,int x,int y){ up[++tot]=(node){Headup[u],x,y}; Headup[u]=tot;}void adddown(int u,int x,int y){ down[++tot1]=(node){Headdown[u],x,y}; Headdown[u]=tot1;}int getfa(int x){ return fa[x]==x?fa[x]:fa[x]=getfa(fa[x]);}void Tarjan_LCA(int u,int pre){ father[u]=pre; fa[u]=u; deep[u]=deep[pre]+1; for (int i=Head[u];i;i=edge[i].next) { int v=edge[i].v; if (v==pre) continue; Tarjan_LCA(v,u); fa[v]=u; } vis[u]=true; for (int i=Headq[u];i;i=que[i].next) if (vis[que[i].v]) lca[que[i].id]=getfa(que[i].v);}void dfs(int u,int pre){ ans[u]-=a[T[u]+deep[u]]+b[T[u]-deep[u]+n]; for (int i=Head[u];i;i=edge[i].next) if (edge[i].v!=pre) dfs(edge[i].v,u); for (int i=Headup[u];i;i=up[i].next) a[up[i].x]+=up[i].y; for (int i=Headdown[u];i;i=down[i].next) b[down[i].x+n]+=down[i].y; ans[u]+=a[T[u]+deep[u]]+b[T[u]-deep[u]+n];}int main(){ scanf("%d%d",&n,&m);tot=0; for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); adde(x,y); adde(y,x); } tot=0; for (int i=1;i<=n;i++) scanf("%d",&T[i]); for (int i=1;i<=m;i++) { scanf("%d%d",&s[i],&t[i]); addq(s[i],t[i],i); addq(t[i],s[i],i); } Tarjan_LCA(1,0); tot=tot1=0; for (int i=1;i<=m;i++) { addup(s[i],deep[s[i]],1); addup(father[lca[i]],deep[s[i]],-1); adddown(t[i],deep[s[i]]-2*deep[lca[i]],1); adddown(lca[i],deep[s[i]]-2*deep[lca[i]],-1); } dfs(1,0); for (int i=1;i<n;i++) printf("%d ",ans[i]); printf("%d\n",ans[n]); system("pause"); return 0;}
T3
#include<bits/stdc++.h>using namespace std;const int MAXN=2000+10;int f[MAXN][MAXN],c[MAXN],d[MAXN],n,m,v,e;double k[MAXN],k_[MAXN],s[MAXN][MAXN][2],ans;void init(){ memset(f,0x3f,sizeof(f)); scanf("%d%d%d%d",&n,&m,&v,&e); memset(s,0x43,sizeof(s)); ans=1e16; for (int i=1;i<=n;i++) scanf("%d",&c[i]); for (int i=1;i<=n;i++) scanf("%d",&d[i]); for (int i=1;i<=n;i++) scanf("%lf",&k[i]),k_[i]=1.0-k[i]; for (int i=1;i<=e;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); if (f[x][y]>z) f[x][y]=f[y][x]=z; } for (int i=1;i<=v;i++) f[i][i]=0; for (int kk=1;kk<=v;kk++) for (int i=1;i<=v;i++) for (int j=1;j<=v;j++) f[i][j]=min(f[i][j],f[i][kk]+f[kk][j]);}int main(){ init(); memset(s[1],0,sizeof(s[1])); s[1][0][1]=1e16; if (n==1) ans=0; for (int i=2;i<=n;i++) for (int j=0;j<=m;j++) { int d1=f[c[i-1]][c[i]],d2=f[c[i-1]][d[i]]; int d3=f[d[i-1]][c[i]],d4=f[d[i-1]][d[i]]; s[i][j][0]=min(s[i-1][j][0]+d1,s[i-1][j][1]+k[i-1]*d3+k_[i-1]*d1); if (j) s[i][j][1]=min(s[i-1][j-1][0]+k[i]*d2+k_[i]*d1,s[i-1][j-1][1]+ k_[i-1]*k_[i]*d1+k_[i-1]*k[i]*d2+k[i-1]*k_[i]*d3+k[i-1]*k[i]*d4); if (i==n) ans=min(ans,min(s[i][j][0],s[i][j][1])); } printf("%.2lf\n",ans); return 0;}
- NOIP2016 DAY1
- 【NOIP2016】Day1
- NOIP2016 Day1
- NOIP2016 Day1
- NOIP2016提高组 DAY1
- NOIP2016提高组day1
- NOIP2016提高组Day1
- NOIP2016 day1玩具谜题
- NOIP2016 Day1 玩具谜题
- NOIP2016提高组Day1题解
- P4059【NOIP2016 DAY1】换教室
- 【noip2016模拟day1】【线段树】【dp】
- 【NOIP2016提高组day1】换教室
- NOIP2016提高组day1 换教室
- NOIP2016 day1 t1 玩具谜题
- NOIP2016提高组Day1 真题测试
- NOIP2016提高组day1试题 玩具谜题
- NOIP2016 day1 T1 玩具谜题 toy 题解
- Leetcode327——Count of Range Sum
- LeetCode-Median of Two Sorted Arrays
- python学习第一天
- MicroStation V8i简体中文版安装及破解教程
- LeetCode 3. Longest Substring Without Repeating Characters
- 【NOIP2016】Day1
- 关于代码重构的一些想法
- 哈希算法
- RSA加密原理与过程
- Coursera 机器学习(by Andrew Ng)课程学习笔记(二)——多元线性回归和正规方程
- JDBC基础
- nginx-配置location块
- Linux学习(四)
- react-native 填坑之旅 数据库存储 realm