比我使用的递归更好的方法(更好的时间复杂度)

时间:2016-01-16 14:52:01

标签: c algorithm recursion dynamic-programming

每个球都有n个特定的重量和成本。必须移除球,使得移除的球的成本最大。附加条件是最后k个球的权重之和应该<=剩余球的权重乘以另一个常数Q(k是常数:给定)。球只能从末端移除。如何最大化成本。我可以使用递归算法解决这个问题。但我想知道如何使用队列降低复杂度O(n)。

 #include<stdio.h>

long int Q, val[100000], wt[100000],k,n;

long int steal(long int l,long int r,long int cut)
{
    long int i,sum,steal1, steal2 ,X, Y = 0;
    for(i = r; i > r - k; i--)
        Y = Y + wt[i];
    sum = 0;
    for(i = l; i <= r; i++)
        sum = sum + wt[i];
    X = sum - Y;
    if(X * Q < Y)
        return 0;
    else
    {
        steal1 = steal(l, r-1, r);
        steal2 = steal(l+1, r, l);
        if(steal1 == 0 && steal2 != 0)
            return steal2 ;
        else if(steal1 != 0 && steal2 == 0)
            return steal1 ;
        else if(steal1 == 0 && steal2 == 0)
        {
            if(r-l+1 == n)
                return 0;
            else 
                return val[cut];
        }
        else
        {
            if(steal1+val[r] > steal2+val[l])
                return steal1+val[r];
            else 
                return steal2+val[l];
        }
    }
}

int main()
{
    long int i;
    scanf("%ld %ld %ld", &n, &k, &Q);
    for(i = 0; i < n; i++)
        scanf("%ld", &wt[i]);
    for(i = 0; i < n; i++)
        scanf("%ld", &val[i]);
    printf("%ld\n", steal(0, n - 1,n));
    return 0;
}

测试用例: 5 2 1(分别为n,k和q) 5 4 6 3 2(n个球的重量) 3 2 4 2 2(每个球的价值)

答案:5

1 个答案:

答案 0 :(得分:1)

要修复的事情:

  1. 您有一些使用100000个元素声明的数组,无论n的实际值是什么,而不是它们的大小。如果100000&lt; n,那么数组太小,你会因为索引越界而遇到问题。如果n&lt; 100000,那么你浪费了很多记忆。不是使用100000元素初始化数组,而是使用n元素初始化它们。请阅读this了解更多信息。
  2. 您可以在阅读输入时使用insertion sort,按重量,值或某些公式对元素进行排序,这样您就可以按重量,数值或某些符合您需求的公式来区分球更好。
  3. 使用递归你正在使用堆栈。您可以使用自定义stack来实现此目的。
  4. 如果要对球进行排队,则队列可以是在2处创建的队列。
  5. 如果您想要最好的解决方案,那么您需要为您的目的实施Divide et Impera