我怎样才能确定这种情况的确切复发?

时间:2015-08-05 04:48:28

标签: algorithm

  

N座建筑物连续建造,从左到右编号为1到N.        蜘蛛侠在1号楼上,想要达到建筑物编号N.       他可以从建筑物编号i跳到建筑物编号j iff i< j和j-i是2的幂(1,2,4,依此类推)。        这样的举动花费了他的能量|高度[j] - 高度[i] |,其中高度[i]是第i个建筑物的高度。       找到他可以达到建筑物N的最低能量?

     

输入:

     

第一行包含N,建筑物数量。       下一行包含N个以空格分隔的整数,表示数组高度。

     

输出:

     

打印一个整数,即上述问题的答案。

所以,我想到了这样的事情:

int calc(int arr[], int beg, int end, )
{
    //int ans = INT_MIN;
    if (beg == end)
        return 0;
    else if (beg > end)
        return 0;
    else
    {
        for (int i = beg+1; i <= end; i++ ) // Iterate over all possible combinations
        {
            int foo = arr[i] - arr[beg]; // Check if power of two or not
            int k = log2(foo);
            int z = pow(2,k);
            if (z == foo) // Calculate the minimum value over multiple values
            {
                int temp = calc(arr,i,end);
                if (temp < ans)
                    temp = ans;
            }
        }
    }
}

以上是我要解决的问题,这是链接:https://www.codechef.com/TCFS15P/problems/SPIDY2 但是,上述重现并不完全正确。我是否必须传递answer的值?

2 个答案:

答案 0 :(得分:2)

我们可以从任何(n-2^0),(n-2^1),(n-2^2)...建筑物到达第n座建筑物。因此,我们需要从1开始处理建筑物。对于每个建筑物i,我们计算从j的任何一个建筑i-j获得的费用,其中int calc(int arr[],int dp[],int n) { // n is the target building for(int i=1; i<=n; i++) dp[i]=LLONG_MAX; //initialize to infinity dp[1]=0; // no cost for starting building for(int i=2; i<=n; i++) { for(int j=1; i-j>=1; j*=2) { dp[i]=min(dp[i], dp[i-j]+abs(arr[i]-arr[i-j])); } } return dp[n]; } 是2的幂,并采取最低成本

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Test;


@Test
public void testWhatIsTheAnswer() {

    JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();

    factoryBean.getInInterceptors().add(new LoggingInInterceptor());
    factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
    factoryBean.setServiceClass(DeepThought.class);
    factoryBean.setAddress("http://localhost:8084/DeepThoughtWS/services/DeepThoughtPort");

    DeepThought service = (DeepThought) factoryBean.create();

    service.whatIsTheAnswer("some answer");

}

时间复杂度为O(n * log(n))。

答案 1 :(得分:0)

首先,您正在检查错误数量的2的幂。跳转必须在建筑物之间进行,这些建筑物在索引中以2的幂分隔,而不是高度不同(这是您正在检查的)。

其次,递归应该根据第一次跳跃的成本和剩余跳跃的成本(通过递归调用获得)来制定。您正在寻找所有合法首跳的最低成本。第一次跳跃是合法的,如果它是一个索引小于N的建筑物,并且在距离当前开始的索引中也是2的幂。

这样的事情应该有效:

int calc(int arr[], int beg, int end)
{
    if (beg == end)
        return 0;
    else if (beg > end)
        throw an exception

    int minEnergy = INFINITY;
    for (int i = 1;        // start with a step of 1
         beg + i <= end;   // test if we'd go too far
         i <<= 1)          // increase step to next power of 2
    {
        int energy = abs(arr[beg + i] - arr[beg])  // energy of first jump
                   + calc(arr, beg + i, end);      // remaining jumps
        if (energy < minEnergy) {
            minEnergy = energy;
        }
    }
    return minEnergy;
}

通过传递迄今为止获得的最小能量,可以大大提高这种搜索的效率。然后,如果abs(arr[beg + i] - arr[beg])不小于该数量,则不需要进行递归调用,因为找到的内容永远不会更小。 (事实上​​,如果abs(arr[beg + i] - arr[beg]) + abs(arr[end] - arr[beg + i])不小于目前为止的最佳解决方案,您可以切断递归,因为蜘蛛侠在构建abs(arr[end] - arr[beg + i])之后必须至少花费beg + i。)添加这种改进是一项练习。 :)