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;
}

浙公网安备 33010602011771号