zoukankan      html  css  js  c++  java
  • TopCoder SRM704 Div1 800 构造

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

    题解

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

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

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

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

    $$forall 1leq 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 1leq 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;
    }
    

      

  • 相关阅读:
    对象属性对话框只能放大不能缩小
    Windows2003 Server升级至SP2后,水晶报表导出EXCEL出错
    磁盘结构损坏且无法读取
    InsusCharacterUtility.dll怎么调用
    会员综合实例
    无法连接SQL Server 2008
    JavaScript alert Utility
    DNS与Active Directory在两台服务器分别布署
    显示用户权限
    焦点新闻图片轮翻广告
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/SRM704-800.html
Copyright © 2011-2022 走看看