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

T1

T2 树

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

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

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

code:

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 int n,a[101][102],c,ans;
  4. 4 void gauss()
  5. 5 {
  6. 6 int c=1;
  7. 7 for(int i=1;i<=n;i++)
  8. 8 {
  9. 9 int r=c;
  10. 10 for(int j=c+1;j<=n;j++)
  11. 11 if(a[r][i]<a[j][i]) r=j;
  12. 12 if(!a[r][i]) continue;
  13. 13 if(r!=c) for(int j=i;j<=n+1;j++)
  14. 14 swap(a[r][j],a[c][j]);
  15. 15 for(int j=1;j<=n;j++)
  16. 16 if(j!=c&&a[j][i]) for(int k=i;k<=n+1;k++)
  17. 17 a[j][k]^=a[c][k];
  18. 18 c++;
  19. 19 }
  20. 20 }
  21. 21 void dfs(int h,int now)
  22. 22 {
  23. 23 if(now>=ans) return;
  24. 24 if(!h)
  25. 25 {
  26. 26 ans=now;
  27. 27 return;
  28. 28 }
  29. 29 if(a[h][h]) dfs(h-1,now+a[h][n+1]);
  30. 30 else
  31. 31 {
  32. 32 if(a[h][n+1]) return;
  33. 33 dfs(h-1,now);
  34. 34 for(int i=h;i>0;i--) a[i][n+1]^=a[i][h];
  35. 35 dfs(h-1,now+1);
  36. 36 for(int i=h;i>0;i--) a[i][n+1]^=a[i][h];
  37. 37 }
  38. 38 }
  39. 39 int main()
  40. 40 {
  41. 41 scanf("%d",&n);
  42. 42 while(n)
  43. 43 {
  44. 44 ans=INT_MAX;
  45. 45 for(int i=1;i<=n;i++)
  46. 46 for(int j=1;j<=n+1;j++)
  47. 47 a[i][j]=0;
  48. 48 for(int i=1;i<n;i++)
  49. 49 {
  50. 50 int x,y;
  51. 51 scanf("%d%d",&x,&y);
  52. 52 a[x][y]=a[y][x]=1;
  53. 53 }
  54. 54 for(int i=1;i<=n;i++) a[i][i]=a[i][n+1]=1;
  55. 55 gauss();
  56. 56 dfs(n,0);
  57. 57 printf("%d\n",ans);
  58. 58 scanf("%d",&n);
  59. 59 }
  60. 60 return 0;
  61. 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. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 int n,to[210],nex[210],head[110],f[110][2],g[110][2];//f按g不按 0不亮1亮
  4. 4 inline int read()
  5. 5 {
  6. 6 int x=0,f=1;
  7. 7 char ch=getchar();
  8. 8 while(ch<'0'||ch>'9')
  9. 9 {
  10. 10 if(ch=='-')
  11. 11 f=-1;
  12. 12 ch=getchar();
  13. 13 }
  14. 14 while(ch>='0'&&ch<='9')
  15. 15 {
  16. 16 x=(x<<1)+(x<<3)+(ch^48);
  17. 17 ch=getchar();
  18. 18 }
  19. 19 return x*f;
  20. 20 }
  21. 21 void write(int x)
  22. 22 {
  23. 23 if(x<0)
  24. 24 {
  25. 25 putchar('-');
  26. 26 x=-x;
  27. 27 }
  28. 28 if(x>9)
  29. 29 write(x/10);
  30. 30 putchar(x%10+'0');
  31. 31 }
  32. 32 inline void add(int a,int b,int d)
  33. 33 {
  34. 34 to[d]=b; nex[d]=head[a]; head[a]=d;
  35. 35 to[d+n-1]=a; nex[d+n-1]=head[b]; head[b]=d+n-1;
  36. 36 }
  37. 37 void dfs(int x,int fa)
  38. 38 {
  39. 39 f[x][0]=g[x][1]=n+1; f[x][1]=1; g[x][0]=0;
  40. 40 int f0,f1,g0,g1,v;
  41. 41 for(int i=head[x];i;i=nex[i])
  42. 42 {
  43. 43 v=to[i];
  44. 44 if(v==fa) continue;
  45. 45 dfs(v,x);
  46. 46 f0=f[x][0]; f1=f[x][1]; g0=g[x][0]; g1=g[x][1];
  47. 47 f[x][0]=min(f1+f[v][0],f0+g[v][0]);
  48. 48 f[x][1]=min(f0+f[v][0],f1+g[v][0]);
  49. 49 g[x][0]=min(g1+f[v][1],g0+g[v][1]);
  50. 50 g[x][1]=min(g0+f[v][1],g1+g[v][1]);
  51. 51 }
  52. 52 }
  53. 53 int main()
  54. 54 {
  55. 55 n=read();
  56. 56 while(n)
  57. 57 {
  58. 58 memset(head,0,sizeof(head));
  59. 59 for(int i=1;i<n;i++) add(read(),read(),i);
  60. 60 dfs(1,0);
  61. 61 write(min(f[1][1],g[1][1])); putchar('\n');
  62. 62 n=read();
  63. 63 }
  64. 64 return 0;
  65. 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. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 const int p=1000000007;
  4. 4 int n,m,k,f[32][32][1<<9][9];
  5. 5 inline int read()
  6. 6 {
  7. 7 int x=0,f=1;
  8. 8 char ch=getchar();
  9. 9 while(ch<'0'||ch>'9')
  10. 10 {
  11. 11 if(ch=='-')
  12. 12 f=-1;
  13. 13 ch=getchar();
  14. 14 }
  15. 15 while(ch>='0'&&ch<='9')
  16. 16 {
  17. 17 x=(x<<1)+(x<<3)+(ch^48);
  18. 18 ch=getchar();
  19. 19 }
  20. 20 return x*f;
  21. 21 }
  22. 22 void write(int x)
  23. 23 {
  24. 24 if(x<0)
  25. 25 {
  26. 26 putchar('-');
  27. 27 x=-x;
  28. 28 }
  29. 29 if(x>9)
  30. 30 write(x/10);
  31. 31 putchar(x%10+'0');
  32. 32 }
  33. 33 int main()
  34. 34 {
  35. 35 n=read(); m=read(); k=read();
  36. 36 f[1][0][0][0]=1;
  37. 37 for(int i=1;i<=n;i++)
  38. 38 for(int j=0;j<=m;j++)
  39. 39 for(int u=0;u<(1<<(k+1));u++)
  40. 40 {
  41. 41 for(int l=min(i,k);l>0;l--)
  42. 42 {
  43. 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. 44 f[i][j][u][l-1]+=f[i][j][u][l]; f[i][j][u][l-1]%=p;
  45. 45 }
  46. 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. 47 }
  48. 48 write(f[n][m][0][0]);
  49. 49 return 0;
  50. 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. Element MenuNav刷新后点击菜单保留选中状态

    正常情况刷新后选中菜单会失去选中的状态,需要把default-active 当前激活菜单的 index保存下来这样刷新后读取 methods方法中增加 getSess() { this.active ...

  2. k8s架构与组件详解

    没有那么多花里胡哨,直接进行一个K8s架构与组件的学习. 一.K8s架构 k8s系统在设计是遵循c-s架构的,也就是我们图中apiserver与其余组件的交互.在生产中通常会有多个Master以实现K ...

  3. JAVA安全基础之代理模式(一)

    JAVA安全基础之代理模式(一) 代理模式是java的一种很常用的设计模式,理解代理模式,在我们进行java代码审计时候是非常有帮助的. 静态代理 代理,或者称为 Proxy ,简单理解就是事情我不用 ...

  4. zip命令常用选项

    大家都知道,在linux上一切皆文件,在实际生产环境中,如果我们需要部署一些系统的服务,我们会将一些软件包提前下载下来统一放到一个文件夹中, 然后将部署的过程用shell或者python写成一个脚本, ...

  5. 珠峰2016,第9期 vue.js 笔记部份

    在珠峰参加培训好年了,笔记原是记在本子上,现在也经不需要看了,搬家不想带上书和本了,所以把笔记整理下,存在博客中,也顺便复习一下 安装vue.js 因为方便打包和环境依赖,所以建意npm  init  ...

  6. Java中short和int的转换

    例子[1]: 第一种情况: short a = 1; a = a + 1; // 这一步会报错 System.out.print(a); 编译器会报错,原因如下: 第二种情况: short a = 1 ...

  7. Hyper-V + WSL2与 VirtualBox 共存

    Hyper-V + WSL2与 VirtualBox 共存 这样的教程网上有很多,我先简单复述一下.真正麻烦的是我遇到的问题--开启 Hyper-V 后我的电脑会多出几个删不掉的虚拟显示器来,会在文章 ...

  8. 【PHP数据结构】插入类排序:简单插入、希尔排序

    总算进入我们的排序相关算法的学习了.相信不管是系统学习过的还是没有系统学习过算法的朋友都会听说过许多非常出名的排序算法,当然,我们今天入门的内容并不是直接先从最常见的那个算法说起,而是按照一定的规则一 ...

  9. GoLang设计模式07 - 责任链模式

    责任链模式是一种行为型设计模式.在这种模式中,会为请求创建一条由多个Handler组成的链路.每一个进入的请求,都会经过这条链路.这条链路上的Handler可以选择如下操作: 处理请求或跳过处理 决定 ...

  10. spring入门3-jdbcTemplate简单使用和声明式事务

    1.JdbcTemplate简单使用 1.1.引入相关依赖包 <dependency> <groupId>mysql</groupId> <artifactI ...