To construct a direction graph that does not exceed 20 without a single loop, and the node number from 0 to n-1, so that the number of Hamiltonian paths from 0 to N-1 is exactly K.
Feeling completely without thought. Do not know how to construct.
To see the other people's code, the original can be made 1<-2<-... <-18 a path, and then 1-18 to the number of nodes larger than the edge. In this case, there is only one way back, so if I am currently in the j,j>i, then I need to go from J to j-1 immediately to i+1 and then back. This is equivalent to each node has a choice or not selected two states, if the choice is from the first in front of its small selection of nodes to jump over, do not choose words from the i+1 come. So if there is a 0->i, it is equivalent to contributing 218−i−1 (1≤I<18) 2^{18-i-1} (1\le I (since 18 is required and 19 cannot go back to 18).
If you can't do it, then mess it up.
If you say that a figure is arbitrarily determined, how to find the number of paths. That requires O (220202) O (2^{20}20^2)-like pressure DP. But we can first ask for 0->n-1 's Hamiltonian path number, we can first find i−>19,1≤i<19 i->19,1\le I, and then even from 0 out of the side, so that is the question of whether there is a subset and exactly K.
We know (189) \binom{18}{9} is a very large number, so if the i->19 path number is in K9 K\over 9 near the random, then it is easy to accidentally gather a K. So we can divide the total of the two sides until we find a total number of edges where the number of random i−>19 i->19 path numbers will be close to the K9 K\over 9, and then there will always be random.
In this case, the time complexity is O (2nn2logn) ≈109 O (2^nn^2\log N) ≈10^9. So the constant comparison of DP can be done by heart. I was wrong at first. The time complexity is thought to be O (2NNLOGN) O (2^nn\log N) is no tube, the results of the sample can not get through ...
Code:
#include <bits/stdc++.h> using namespace std;
const int N=20,N=20;
typedef long Long LL;
Class Hamiltonianconstruction {public:pair<int,int> edge[n*n];
int Etot;
LL f[1<<n][n];
LL s[1<<n];
int prev[n];
int bit[1<<n];
inline void cal (int mid) {random_shuffle (Edge,edge+etot);
memset (prev,0,sizeof (prev));
for (int i=mid;i--;) prev[edge[i].second-1]|=1<<edge[i].first-1;
memset (F,0,sizeof (f));
f[1<<n-2][n-2]=1; for (int i=1;i<1<<n-1;++i) for (int j=i,x;j;j^=1<<x) if (f[i][x=bit[j& -J]]) for (int k=prev[x]&~i,y;k;k^=y) {y=k
&-k;
F[I|Y][BIT[Y]]+=F[I][X];
for (int i=n-2;i--;) s[1<<i]=f[(1<<n-1) -1][i]; for (int i=1;i<1<<n-2;++i) s[i]=s[i^i&-i]+s[i&-i];
} inline vector<string> construct (int k) {for (int i=0;i<n;++i) bit[1<<i]=i; for (int i=n-1;--i;) for (int j=n;--j;) if (i!=j) edge[
Etot++]=make_pair (I,J);
Vector<string> ans (n,string (n, ' n '));
int l=0,r=100;
while (r-l>1) {int mid=l+r>>1;
Cal (mid); for (int i=1<<n-2;i--;) if (s[i]==k) {for (int j=mid;j
--;) ans[edge[j].first][edge[j].second]= ' Y ';
for (int j=n-2;j--;) if (i>>j&1) ans[0][j+1]= ' Y ';
return ans;
LL sum=0;
for (int i=n-2;i--;) sum+=s[1<<i]; if (sum>=k<<1) R=mid;
else L=mid;
for (;;)
{cal (R); for (int i=1<<n-2;i--;) if (s[i]==k) {for (int j=r;j--
;) ans[edge[j].first][edge[j].second]= ' Y ';
for (int j=n-2;j--;) if (i>>j&1) ans[0][j+1]= ' Y ';
return ans; }
}
}
};
Summary:
When ① constructs, you can consider special situations, or depending on the particular nature of the topic. For example, to construct a graph, you can first consider a chain, a complete graph, a tree.
② If there is no structured thinking, try randomization.
③ must be a good time complexity.