C++ 降低递归函数的算法时间复杂度
这是函数f(T,k)的代码,其中 这是一个递归函数,我需要降低复杂性,但我不知道如何降低复杂性。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
有人能帮我吗 这是问题文本:
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