C++ 降低递归函数的算法时间复杂度

C++ 降低递归函数的算法时间复杂度,c++,algorithm,recursion,time-complexity,C++,Algorithm,Recursion,Time Complexity,这是函数f(T,k)的代码,其中 这是一个递归函数,我需要降低复杂性,但我不知道如何降低复杂性。 有人能帮我吗 这是问题文本: 100000007名玩家参与此游戏,赢家由随机选择决定。为了让选择变得随机,该公司为选择该球员制定了严格的规则。首先,他们用从0到100000006的识别号对玩家进行编号。然后他们选择一个包含N个元素和数字k的数组A。然后,他们将获胜者定义为具有识别号f(A,k)mod(10000007)的玩家 #包括 #包括 使用名称空间std; int N,k,a; 向量; 内部f

这是函数f(T,k)的代码,其中

这是一个递归函数,我需要降低复杂性,但我不知道如何降低复杂性。
有人能帮我吗

这是问题文本:
100000007名玩家参与此游戏,赢家由随机选择决定。为了让选择变得随机,该公司为选择该球员制定了严格的规则。首先,他们用从0到100000006的识别号对玩家进行编号。然后他们选择一个包含N个元素和数字k的数组A。然后,他们将获胜者定义为具有识别号f(A,k)mod(10000007)的玩家

#包括
#包括
使用名称空间std;
int N,k,a;
向量;
内部fja(矢量,内部k){
长suma=0;
如果(k==0){//如果k==0,则计算第一个所述函数
对于(auto it=A.begin();it!=A.end();it++)suma=(suma+(*it))%(100000007);//因为suma非常大,所以modou在那里
回归苏玛;
}else{//如果k>0,则计算第二个函数
int duzina=A.size();//duzina是A(T)的长度
for(int i=0;iN>>k;//元素数和k
对于(int i=0;i>a;
A.向后推(A);//所有元素
}

cout我实现了非递归版本,只基于循环,但是它有
O(k*n^4)
所以对于最大的
10^5
n和k值,它会太慢

我提供了递归解供参考,它可以解N和k多达10,我的非递归解可以解N和k多达100

我确信在我的解决方案中,通过算法优化可以消除一些循环。但我仍然不知道如何解决非常大的10^5值的任务

在当前的main()函数中,N和k都是10,仅用于测试,为了只留下快速版本,您可以将N和k从10更改为100,并注释掉f_ref()调用。f_ref()是引用递归函数,f_fast()是我更快的变体

N=100和k=100时的输出:

37190121

您发布的代码有什么问题?@AlanBirtles对于N和k的大输入来说太慢了。我想降低时间复杂性。@Sip_uu您能提供N和k的限制吗?以及时间限制。N和k的大值到底是什么?您期望什么运行时?您看到什么运行时?您启用了编译器优化吗?更改
fja
使用一对迭代器而不是向量可以避免复制数据。谢谢。非常好!
#include <iostream>
#include <vector>

using namespace std;

int N,k,a;
vector<int>A;


int fja(vector<int>A,int k){
    long long suma=0;
    if(k==0){// If k==0 calculate the first said function
        for(auto it=A.begin();it!=A.end();it++)suma=(suma+(*it))%(1000000007);//Moduo is there because suma is very big
        return suma;
    }else{//If k>0 calculate the second function 
        int duzina=A.size();//duzina is length of A (T)
        for(int i=0;i<duzina;i++){//Going through the first and second sum of second function
            for(int j=i;j<duzina;j++){
                vector<int>b(A.begin()+i,A.begin()+j+1);//Creating new vector (array) to pass it into the new function call
                suma=(suma+fja(b,k-1))%(1000000007);//Moduo is there because suma is very big
            }
        }
        return suma;
    }

}

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin>>N>>k; //Number of elements and k
    for(int i=0;i<N;i++){
        cin>>a;
        A.push_back(a);//All the elements
    }



    cout<<fja(A,k);

}
#include <cstdint>
#include <vector>
#include <iostream>

typedef uint32_t u32;
typedef int64_t i64;
typedef uint64_t u64;

enum { mod = 100000007 };

i64 f_ref(std::vector<i64> const & T, size_t begin, size_t end, size_t k) {
    i64 sum = 0;
    if (k == 0)
        for (size_t i = begin; i < end; ++i)
            sum = (sum + T[i]) % mod;
    else
        for (size_t i = begin; i < end; ++i)
            for (size_t j = i; j < end; ++j)
                sum = (sum + f_ref(T, i, j + 1, k - 1)) % mod;
    return sum;
}

i64 f_fast(std::vector<i64> const & T, size_t k) {
    size_t N = T.size();
    std::vector<std::vector<i64>> mc, mn;
    for (size_t n = 1; n <= N; ++n) {
        mc.resize(mc.size() + 1);
        for (size_t j = 0; j < n; ++j)
            mc.back().push_back(((n + (n - 2 * j)) * (j + 1) / 2) % mod);
    }
    for (size_t ik = 0; ik + 1 < k; ++ik) {
        mn.clear();
        mn.resize(N);
        for (size_t n = 1; n <= N; ++n) {
            mn[n - 1].resize(n);
            for (size_t i = 0; i < n; ++i)
                for (size_t j = i; j < n; ++j)
                    for (size_t l = 0; l <= j - i; ++l)
                        mn[n - 1][i + l] = (mn[n - 1][i + l] + mc[j - i][l]) % mod;
        }
        mc = mn;
    }
    i64 sum = 0;
    for (size_t i = 0; i < N; ++i)
        sum = (sum + mc.back()[i] * (T[i] % mod)) % mod;
    return sum;
}

int main() {
    std::vector<i64> a;
    for (size_t i = 0; i < 10; ++i)
        a.push_back(i + 1);
    size_t k = 10;
    std::cout << f_ref(a, 0, a.size(), k) << " " << f_fast(a, k) << std::endl;
    return 0;
}
78689325 78689325
37190121