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
的值?
答案 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
。)添加这种改进是一项练习。 :)