【问题标题】:Given an initial population x, what is the least steps to get to desired population y给定初始种群 x,达到所需种群 y 的最少步骤是多少
【发布时间】:2014-03-19 20:46:51
【问题描述】:

给定一个初始种群 x 和一个确切的期望种群 y, 到达 y 的最少步数是多少 使用三个函数 A{x+1}, B{x+2}, C{x+x}

我的方法

#include<iostream>
using namespace std;

int fA (int x)
{
    return x+1;
}
int fB(int x)
{
    return x+2;
}
int fC(int x)
{
    return x+x;
}

int main()
{
    int s, n;
    cin>>s>>n;

    int counter=0;

    while(fC(s)<=n)
    {
        s=fC(s);
        counter++;
    }

    while(fB(s)<=n)
    {
        s=fB(s);
        counter++;
    }

    while(fA(s)<=n)
    {
        s=fA(s);
        counter++;
    }

    cout<<counter;

    return 0;
}

我假设先从增长最快的函数开始,然后再从其他函数开始是错误的,

欢迎任何帮助。

【问题讨论】:

  • 也许你需要检查一下 s
  • while 循环每次都会检查
  • 说你从 x=1 开始,想要到达 y=7,按照我的逻辑,你像这样 1->2->4->6->7 四个步骤,但方法更短是 1->3->5->7 三步。
  • 嗯,一般来说,1人口根本无法繁殖。但是您可以在程序的开头添加一些内容以涵盖该边缘情况 - 即if(s == 1){s=fB(s); counter++;}

标签: c++ function population


【解决方案1】:

一个问题是“最快”取决于x。例如,最初使用x=0,然后x+x 不会增长太多,而且使用x=1 最快的是x+2,而不是x+x

我会使用直接的全搜索方法:

int min_steps(int x, int y) {
    std::set<int> active, seen;
    active.insert(x); seen.insert(x);
    int steps = 0;
    while (active.size() && active.find(y) == active.end()) {
        // `active` is the set of all populations that we can
        // reach in `steps` number of steps or less not greater
        // than the target value `y`.
        // The next set is computed by starting from every value
        // and applying every possible growth function.
        // `seen` is the set of all values we saw before to avoid
        // adding a value that has been checked before.
        steps++;
        std::set<int> new_active;
        for (std::set<int>::iterator i=active.begin(),e=active.end();
             i!=e; ++i) {
            for (int f=0; f<3; f++) {
                int z;
                switch(f) {
                    case 0: z = *i + 1; break;
                    case 1: z = *i + 2; break;
                    case 2: z = *i + *i; break;
                }
                if (z <= y && seen.find(z) == seen.end()) {
                    new_active.insert(z);
                    seen.insert(z);
                }
            }
        }
        active = new_active;
    }
    return active.size() ? steps : -1;
}

鉴于 x

【讨论】:

    【解决方案2】:

    我将描述一个一般策略,期望函数应用程序的最大数量。有3例。在所有情况下假设 x

    情况 1 如果 X 和 Y 在最高有效位上逐位一致。

    A(x) = x + 1 ----> 如果最低有效位为 0,则将其更改为 1。 C(x) = x + x = 2*x ----> 将 x 位串左移 1

    例如

    x = 9 and y = 37, so 
    X = 1001, Y= 100101
    

    因此,您可以使用 C 两次将 X 向左移动 2 9+9 ---> 18 + 18 ---> 36 或 X = 10010 (18) 然后 100100 (36) 然后加 1 得到 37。

    X = {1001,10010,100100,100101}
    

    所以 3 个应用程序。所以在情况 1 中,策略将是重复应用 C 和 A 并建立 X 以按位匹配 Y。每次移位需要 1 个 C 操作,生成 1 需要 1 个 A 操作。因此,在情况 1 中,它将采用 Length(Y) - Length(X)(C 操作的数量)+ 最不重要的 1 的数量Y 位(A 操作)。在最坏的情况下,它将全为 1 或 2*(Length(Y) - Length(X))。在这种情况下,使用 B 没有帮助。 最坏的情况是 O(Length(Y)) = O(log(y))

    案例 2 (x

    在这种情况下,使用 B 比 C 更快地添加到 X,并且在某些情况下(如上所述)使用 B 而不是情况 1 的一般策略会更好 1。

    所以如果 x = 1 和 y = 7,而不是

    X = {1, 10, 11, 110, 111}, you can skip one step by using B
    X = {1, 11, 110, 111}
    

    案例 3. X 和 Y 不兼容。

    如果 X 和 Y 在最高有效位上不一致,则需要通过应用 B 和 A 来修复 X。

    例子

    X = 110 (6) Y = 101011 (43)
    
    strat  X = {110,1000,1010,10100,10101,101010,101011}
    

    在上面,X 在前 4 位有效位中固定为与 Y 一致,然后一旦完成,对案例 1 使用strat。宽松的上限将是 x/2(应用 B x/2 次 = x) .

    预计总体复杂度为 O(x) + O(log(y)),这似乎与公认答案的图表大体一致。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 2019-09-28
      • 2015-02-25
      • 2019-10-04
      • 1970-01-01
      • 1970-01-01
      • 2013-12-29
      相关资源
      最近更新 更多