【题解】NOIP 2007 提高组

A. 统计数字

Problem

按照题意模拟即可。

B. 字符串的展开

Problem

按照题意模拟即可。

注意一些特判:

  • 开头字符也可能为 '\(-\) '。
  • 可能有连续的 ‘ \(-\) ’。

C. 矩阵取数游戏

Problem

题意:在 \(n\times m\) 的非负矩阵中取数,需要满足以下条件:

  • 每次从每一行取走一个元素,共 \(n\) 个。经过 \(m\) 次后取完矩阵内所有元素。
  • 每次只能在一行的行首或行尾取数。
  • 每行取数的得分 = 被取走的元素\(\times 2^i\),其中 \(i\) 表示第 \(i\) 次取数。最后的总得分为各行得分之和。

求最大总得分。

\(1\le n,m\le 80\)\(0\le a_{ij}\le1000\)

不妨先观察样例:

2 3
1 2 3
3 4 2

82

其中 \(82=2^1\times(1+2)+2^2\times(2+3)+2^3\times(3+4)\)

\(82=(2^1\times1+2^2\times2+2^3\times3)+(2^1\times2+2^2\times3+2^3\times4)\)

发现每行之间取数都互不干扰,即可以一行一行dp,最后对每行答案求和。

容易想到令 \(f[i][j]\) 为左边取 \(i\) 个数,右边取 \(j\) 个数的最大得分。

\(f[i][j]=\max(f[i-1][j]+2^{i+j}\times a[i],f[i][j-1]+2^{i+j}\times a[m-j+1])\)

答案为 \(\max(f[i][m-i]),i\in[1,m]\)

long long ,记得用 __int128

D. 树网的核

Problem

题意:给出一颗 \(n\) 个节点的无根树,有如下定义。

偏心距(ECC):路径 \(F\) 的 ECC 指树网中距路径 \(F\) 最远的点到路径 \(F\) 的距离。

树网的核:在直径上找一段路径 \(F\) 使长度不超过 \(s\) 且 ECC 最小,必要时可以为一个节点。

求满足上述条件的最小 ECC 。

\(2\le n \le 300\)\(0\le s \le 10^3\)\(1\le u,v\le n\)\(0\le w \le 10^3\)

图中直径为:\(A\sim B,A\sim C\)

\(s=11\),树网的核为 \(DEFG\),偏心距为 \(8\)

\(s=0~2\),树网的核为 \(F\),偏心距为 \(12\)

首先,可以看到 \(n\) 究极小,所以考虑暴力:

考虑找到树的直径,记录两个端点,枚举每一段长度不超过\(s\)的路径,逐一比较\(ECC\)

那么如何求一段路径的偏心距?

我们以图中 \(s=11\) 时的情况为例,树网的核为 \(DEFG\),偏心距为路径 \(BF(4+2+2=8)\)

看图容易推出 $dis(B,F)=( dis(B,D)+dis(G,B)-dis(D,G) ) $。

于是我们得到:\(ECC(i,j)=( dis(i,k)+dis(j,k)-dis(i,j))\div2\)

其中 \(k\in[1,n]\),可以用一层循环枚举 \(k\),求出最小 \(ECC\)

至于 \(dis(i,k)\)\(dis(j,k)\)\(dis(i,j)\),我们只需跑 \(floyd\) 即可。

但由于 \(floyd\) 用邻接矩阵,所以我们只能 \(O(n^2)\) 求直径,整个算法复杂度为 \(O(n^3)\)

细节:容易得到一个点 \(k\) 在直径 \(i\)~\(j\) 上,那么 \(dis[i][k]+dis[k][j]=dis[i][j]\),否则 continue。


【题解】NOIP 2007 提高组
https://kisuraop.github.io/posts/7f934b5.html
作者
KisuraOP
发布于
2020年12月2日
许可协议