TopCoder SRM704 Div1 800 构造

原文链接https://www.cnblogs.com/zhouzhendong/p/SRM704-800.html

题解

考虑构造一个 $n = 20$ 的图。

先把所有 $i$ 都连向 $i-1$ ,对于所有 $i,j(1\leq i<j<n)$,加边 $i->j$。

设 $f(i)$ 表示从点 $i$ 开始经过 $i\cdots n-1$ 这些点的路径条数,则:

$$f(19) = f(18) = 1$$

$$\forall 1\leq i<18,f(i) = 2^{17-i}$$

证明:

$f(19)=f(18)=1$ 显然。

假设现在从点 $a$ 走到了点 $b(a<b)$,为了经过 $a,b$ 之间的点,接下来只能从 $b$ 往回走,直到走到 $a+1$,接下来只能往标号更大的节点走,而且 $a+1,a+2,\cdots b-1,b$ 已经被经过了,所以接下来的方案数就是 $f(b)$ 。所以 $\forall 1\leq i<18,f(i) = \sum_{j=i+1}^{18} f(j)=2^{17-i}$ 。

对于节点0的连法就简单了,我们既然得到了这么多形如 $2^t$ 的 $f(i)$ ,那么直接将 $k$ 转成二进制表示之后连一下就好了。

代码

#include <bits/stdc++.h>
using namespace std;

class HamiltonianConstruction {
public:
  vector<string> construct(int k);
}gg;
vector<string> HamiltonianConstruction::construct(int k) {
  vector<string> g;
  int n=20;
  string s="";
  for (int i=0;i<20;i++)
    s+="N";
  g.clear();
  for (int i=0;i<20;i++)
    g.push_back(s);
  for (int i=1;i<20;i++){
    g[i][i-1]='Y';
    for (int j=i+1;j<20-1;j++)
      g[i][j]='Y';
  }
  g[18][19]='Y';
  int c=17;
  while (k){
    if (k&1)
      g[0][c]='Y';
    k>>=1,c--;
  }
  return g;
}

  

猜你喜欢

转载自www.cnblogs.com/zhouzhendong/p/SRM704-800.html
今日推荐