带着爆0的心态考的试,没想到整了个假rk2 (炸鱼大佬wtz忒强了OTZ


T1 景区路线规划

这题对刚学完概率期望的我来说简直水爆了好吗。。

因为存在时间限制,不好跑高斯消元,就直接跑dp就完了。

令i为当前所在景点,j为已过时间,

f[i][j]=∑f[u][j-t[k]-c[i]]/out,(u与i联通,k为u,i,之间边的编号)

因为每次在合法的景点中做选择,所以out并不是u的出度,而是u可选的合法景点,每次要遍历一遍求得。

code:

 1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,m,k,st[20001],to[20001],nex[20001],head[101],c[101],t[20001],h1[101],h2[101];
4 double f1[101][481],f2[101][481],ans1,ans2;
5 inline void add(int a,int b,int e,int d)
6 {
7 st[d]=a; to[d]=b; nex[d]=head[a]; head[a]=d; t[d]=e;
8 st[d+m]=b; to[d+m]=a; nex[d+m]=head[b]; head[b]=d+m; t[d+m]=e;
9 }
10 inline double dfs1(int loc,int tim)
11 {
12 if(f1[loc][tim]) return f1[loc][tim];
13 int out=0;
14 for(int i=head[loc];i;i=nex[i])
15 {
16 int v=to[i];
17 if(tim+t[i]+c[v]<=k) out++;
18 }
19 f1[loc][tim]=h1[loc];
20 if(!out) return f1[loc][tim];
21 for(int i=head[loc];i;i=nex[i])
22 {
23 int v=to[i];
24 if(tim+t[i]+c[v]<=k)
25 f1[loc][tim]+=dfs1(v,tim+t[i]+c[v])/out;
26 }
27 return f1[loc][tim];
28 }
29 inline double dfs2(int loc,int tim)
30 {
31 if(f2[loc][tim]) return f2[loc][tim];
32 int out=0;
33 for(int i=head[loc];i;i=nex[i])
34 {
35 int v=to[i];
36 if(tim+t[i]+c[v]<=k) out++;
37 }
38 f2[loc][tim]=h2[loc];
39 if(!out) return f2[loc][tim];
40 for(int i=head[loc];i;i=nex[i])
41 {
42 int v=to[i];
43 if(tim+t[i]+c[v]<=k)
44 f2[loc][tim]+=dfs2(v,tim+t[i]+c[v])/out;
45 }
46 return f2[loc][tim];
47 }
48 int main()
49 {
50 scanf("%d%d%d",&n,&m,&k);
51 for(int i=1;i<=n;i++)
52 scanf("%d%d%d",&c[i],&h1[i],&h2[i]);
53 for(int i=1;i<=m;i++)
54 {
55 int x,y,z;
56 scanf("%d%d%d",&x,&y,&z);
57 add(x,y,z,i);
58 }
59 for(int i=1;i<=n;i++)
60 {
61 ans1+=dfs1(i,c[i]);
62 ans2+=dfs2(i,c[i]);
63 }
64 ans1/=n; ans2/=n;
65 printf("%.5lf %.5lf",ans1,ans2);
66 return 0;
67 }

T1

T2 树

有两种解法,可以跑树状dp,也能高斯消元之后搜出最优解。

考场上没想太多,直接打了个异或高斯消元,结果把第n+1维和解的关系搞乱了,还没搜多组解,捞了40。。

把方程组消元后会出现若干个自由元,通过搜索与回溯遍历每组合法的解,最后找到最优解。

code:

 1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,a[101][102],c,ans;
4 void gauss()
5 {
6 int c=1;
7 for(int i=1;i<=n;i++)
8 {
9 int r=c;
10 for(int j=c+1;j<=n;j++)
11 if(a[r][i]<a[j][i]) r=j;
12 if(!a[r][i]) continue;
13 if(r!=c) for(int j=i;j<=n+1;j++)
14 swap(a[r][j],a[c][j]);
15 for(int j=1;j<=n;j++)
16 if(j!=c&&a[j][i]) for(int k=i;k<=n+1;k++)
17 a[j][k]^=a[c][k];
18 c++;
19 }
20 }
21 void dfs(int h,int now)
22 {
23 if(now>=ans) return;
24 if(!h)
25 {
26 ans=now;
27 return;
28 }
29 if(a[h][h]) dfs(h-1,now+a[h][n+1]);
30 else
31 {
32 if(a[h][n+1]) return;
33 dfs(h-1,now);
34 for(int i=h;i>0;i--) a[i][n+1]^=a[i][h];
35 dfs(h-1,now+1);
36 for(int i=h;i>0;i--) a[i][n+1]^=a[i][h];
37 }
38 }
39 int main()
40 {
41 scanf("%d",&n);
42 while(n)
43 {
44 ans=INT_MAX;
45 for(int i=1;i<=n;i++)
46 for(int j=1;j<=n+1;j++)
47 a[i][j]=0;
48 for(int i=1;i<n;i++)
49 {
50 int x,y;
51 scanf("%d%d",&x,&y);
52 a[x][y]=a[y][x]=1;
53 }
54 for(int i=1;i<=n;i++) a[i][i]=a[i][n+1]=1;
55 gauss();
56 dfs(n,0);
57 printf("%d\n",ans);
58 scanf("%d",&n);
59 }
60 return 0;
61 }

T2高斯消元

树规做法还没整出来,等更新8(咕咕咕
5.30 upd:  竟然没鸽,太感动了
没想到树规代码如此简单OTZ(虽然感觉思路很难想
定义状态数组f[i][1],f[i][0],g[i][1],g[i][0],f表示当前点按了开关,g表示没按;第二维0表示按后这个点亮灯,1表示按后不亮。
状态通过子节点和自己的其他状态进行转移:
当前点按开关,子节点就必须不亮;当前点不亮,要么自己原来不亮,子节点按了,要么自己原来就亮,子节点不动。反之亦然。
思路有了,状态转移方程还是很好想的。最后输出f[1][1]与g[1][0]的较小值。
code:

 1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,to[210],nex[210],head[110],f[110][2],g[110][2];//f按g不按 0不亮1亮
4 inline int read()
5 {
6 int x=0,f=1;
7 char ch=getchar();
8 while(ch<'0'||ch>'9')
9 {
10 if(ch=='-')
11 f=-1;
12 ch=getchar();
13 }
14 while(ch>='0'&&ch<='9')
15 {
16 x=(x<<1)+(x<<3)+(ch^48);
17 ch=getchar();
18 }
19 return x*f;
20 }
21 void write(int x)
22 {
23 if(x<0)
24 {
25 putchar('-');
26 x=-x;
27 }
28 if(x>9)
29 write(x/10);
30 putchar(x%10+'0');
31 }
32 inline void add(int a,int b,int d)
33 {
34 to[d]=b; nex[d]=head[a]; head[a]=d;
35 to[d+n-1]=a; nex[d+n-1]=head[b]; head[b]=d+n-1;
36 }
37 void dfs(int x,int fa)
38 {
39 f[x][0]=g[x][1]=n+1; f[x][1]=1; g[x][0]=0;
40 int f0,f1,g0,g1,v;
41 for(int i=head[x];i;i=nex[i])
42 {
43 v=to[i];
44 if(v==fa) continue;
45 dfs(v,x);
46 f0=f[x][0]; f1=f[x][1]; g0=g[x][0]; g1=g[x][1];
47 f[x][0]=min(f1+f[v][0],f0+g[v][0]);
48 f[x][1]=min(f0+f[v][0],f1+g[v][0]);
49 g[x][0]=min(g1+f[v][1],g0+g[v][1]);
50 g[x][1]=min(g0+f[v][1],g1+g[v][1]);
51 }
52 }
53 int main()
54 {
55 n=read();
56 while(n)
57 {
58 memset(head,0,sizeof(head));
59 for(int i=1;i<n;i++) add(read(),read(),i);
60 dfs(1,0);
61 write(min(f[1][1],g[1][1])); putchar('\n');
62 n=read();
63 }
64 return 0;
65 }

T2树形DP

(不知道为什么不加return 0最后一个点会WA,属实迷惑

 

T3 奇怪的道路

k<=8,可以想到状压。(但当时没时间没思路只能拿特判跟组合数骗分,结果没打longlong骗的还没输出0骗的多。。。

思路有点像动物园,第i个点前后不能兼顾,只考虑一边即可,另一边由之后的点保证。这里考虑之前的点。

状态用0,1表示该点连边的奇偶,另外除了考虑之前k个点的连边,还要考虑当前点,所以状态压k+1位。

状态数组考虑开四维,第一维点数,第二维边数,第三维状态,第四维l表示已更新到第i-l个点,对转移进行限制(不然会发生重复计数

对于第i个点,连了j条边,状态为u,更新到第i-l个点:

如果连边:f[i][j+1][u^1^(1<<l)][l]+=f[i][j][u][l]

如果不连:f[i][j][u][l-1]+=f[i][j][u][l]

当l已转移至0时向下一个点转移:f[i+1][j][u<<1][min(i,k)]+=f[i][j][u][0]

code:

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int p=1000000007;
4 int n,m,k,f[32][32][1<<9][9];
5 inline int read()
6 {
7 int x=0,f=1;
8 char ch=getchar();
9 while(ch<'0'||ch>'9')
10 {
11 if(ch=='-')
12 f=-1;
13 ch=getchar();
14 }
15 while(ch>='0'&&ch<='9')
16 {
17 x=(x<<1)+(x<<3)+(ch^48);
18 ch=getchar();
19 }
20 return x*f;
21 }
22 void write(int x)
23 {
24 if(x<0)
25 {
26 putchar('-');
27 x=-x;
28 }
29 if(x>9)
30 write(x/10);
31 putchar(x%10+'0');
32 }
33 int main()
34 {
35 n=read(); m=read(); k=read();
36 f[1][0][0][0]=1;
37 for(int i=1;i<=n;i++)
38 for(int j=0;j<=m;j++)
39 for(int u=0;u<(1<<(k+1));u++)
40 {
41 for(int l=min(i,k);l>0;l--)
42 {
43 if(j<m) f[i][j+1][u^1^(1<<l)][l]+=f[i][j][u][l], f[i][j+1][u^1^(1<<l)][l]%=p;
44 f[i][j][u][l-1]+=f[i][j][u][l]; f[i][j][u][l-1]%=p;
45 }
46 if(i<n&&(!(u>>k)&1)) f[i+1][j][u<<1][min(i,k)]+=f[i][j][u][0], f[i+1][j][u<<1][min(i,k)]%=p;
47 }
48 write(f[n][m][0][0]);
49 return 0;
50 }

T3

一些感受与反思


成绩貌似还行,但好像也没啥很厉害的地方。。

自由元的深搜应该也不难想,但考场上因为感觉很麻烦就没管它;T3一看求方案数就感觉是排列组合,瞬间头大...

自认为还有很多需要磨砺的地方,不管是思路还是代码能力方面。

未来的路还很长啊......

2021.5.24考试总结 [NOIP模拟3]的更多相关文章

  1. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  2. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  3. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

  4. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  5. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  6. 2021.10.18考试总结[NOIP模拟76]

    T1 洛希极限 不难发现每个点肯定是被它上一行或上一列的点转移.可以预处理出每个点上一行,上一列最远的能转移到它的点,然后单调队列优化. 预处理稍显ex.可以用并查集维护一个链表,记录当前点之后第一个 ...

  7. 2021.10.7考试总结[NOIP模拟71]

    信心赛,但炸了.T3SB错直接炸飞,T4可以硬算的组合数非要分段打表求阶乘..T2也因为一个细节浪费了大量时间.. 会做难题很好,但首先还是要先把能拿的分都拿到. T1 签到题 结论:总可以做到对每个 ...

  8. 2021.9.20考试总结[NOIP模拟57]

    (换个编辑器代码就SB地不自动折叠了.. T1 2A 考察快读的写法. $code:$ T1 #include<bits/stdc++.h> #define scanf SCANF=sca ...

  9. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

随机推荐

  1. AI异构通信:重压下的突围,华为P50系列的卓越体验

    撰文 |懂懂 编辑 | 秦言 来源:懂懂笔记 "华为不会让消费者失望."华为消费者业务CEO余承东在P50系列发布会上如是说. 今年4月美国对华为第四轮制裁以来,华为终端产品无缘5 ...

  2. Flex语法和常用鼠标手势

    Flex弹性和模型 1.display : flex/inline-flex ;(设置给氟元素) flex : 将对象作为弹性伸缩盒显示: inline-flex : 将对象作为内联块级弹性伸缩显示: ...

  3. Dart简易教程 (1)---数据类型 运算符,类转换换

    从下面开始学习DART编程 以下是一个简单的示例: main(){ var number = 42; print(number);}程序说明,dart是一个强大的脚本类语言,可以不预先定义变量类型 , ...

  4. 为什么在匿名内部类中引用外部对象要加final修饰符

    当所在的方法的形参需要被内部类里面使用时,该形参必须为final. 为什么必须要为final呢? 首先我们知道在内部类编译成功后,它会产生一个class文件,该class文件与外部类并不是同一clas ...

  5. 【PHP数据结构】树和二叉树

    树的概念其实非常地广泛,也非常地常见,大家见到这个词千万不要惊慌,因为真的每天你都能见到树结构在我们生活中的应用.比如说公司的组织结构: 另外像我们家里的族谱,或者说是我们的家庭结构,也是一个典型的树 ...

  6. Linux下Nodejs安装(完整详细)转

    Linux下安装有两种方式,一个是下载源码make编译安装. 另外一种是比较推荐的,直接下载编译好的二进制,官方比较推荐后者. //Linux 64bit version wget --no-chec ...

  7. 探究java的intern方法

    本文主要解释java的intern方法的作用和原理,同时会解释一下经常问的String面试题. 首先先说一下结论,后面会实际操作,验证一下结论.intern方法在不同的Java版本中的实现是不一样的. ...

  8. Java基础系列(10)- 类型转换

    类型转换 由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换.运算中,不同类型的数据先转换为同一类型,然后进行运算. 低 ------------------------------ ...

  9. IDEA - 2019中文版安装教程

    前言 个人安装备忘录 软件简介 IDEA 全称IntelliJ IDEA,是java语言开发的集成环境,在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构.J2EE支持. ...

  10. Mysql Navicate 基础操作与SQL语句 版本5.7.29

    SQL数据的增删改查:此部分所有SQL语句在navicat中与mysql命令行执行效果一样,只是mysql服务端在命令行执行,而navicat只是在客户端的图形化打开操作. 一.进入数据库 .连接数据 ...