我是动态编程的新手,我正在通过解决此问题来学习递归
我的怀疑
1)由于测试用例非常大,如何确定dp
表的大小,据我所知,我们通过n的值确定表的大小;
请让我知道正确的表大小,因为我们不知道要重复多少子问题,我有点困惑;
2)我们知道vector在堆上动态分配内存,并且全局声明一个向量意味着只有指针变量dp
会在global节中占据空间,1000000000* sizeof(int)
会在堆中占据。然后为什么显示错误std::bad alloc
,因为我们可以在堆上分配任意数量的内存
#include<bits/stdc++.h>
using namespace std;
vector <int> dp(1000000001,-1);
int exchange(int n){
if(n<12)
return n;
if(dp[n]!=-1)
return dp[n];
return dp[n] = exchange(n/2)+exchange(n/3)+exchange(n/4);
}
int main(){
int t;
cin>>t;
while(t--){
// memset(dp,-1,sizeof(dp));
int n;
cin>>n;
cout<<exchange(n);
}
}
编辑
注意-> count()函数返回键K在地图容器中的出现次数。如果密钥存在于容器中,则返回1,因为映射仅包含唯一密钥。如果键在地图容器中不存在,则返回0。
它几乎通过了所有测试用例,但未通过1 000 000 000
根据long long int range值,它也应该通过这个
一些负值作为输出;
我认为这是容器映射的问题
#include<bits/stdc++.h>
using namespace std;
map <long long int,long long int> dp;
int exchange(long long int n){
if(n<12)
return n;
if(dp.count(n))
return dp[n];
return dp[n] = exchange(n/2)+exchange(n/3)+exchange(n/4);
}
int main(){
// int t;
// cin>>t;
while(1){
// memset(dp,-1,sizeof(dp));
long long int n;
cin>>n;
cout<<exchange(n)<<endl;
}
}
答案 0 :(得分:1)
您可以通过执行以下操作来避免眼前的问题:
str = "1 $nbsp; 2 3 4"
var new_str = str_replace(" ", '', $str);
这将根据输入的vector <int> dp;
// ....
cin>>t;
dp = std::vector<int>(t, -1);
动态分配内存,如果用户输入的值太大,您可以使用异常来捕获。
答案 1 :(得分:1)
尽管您的输入大小可能非常大,但请注意,不会检查表的绝大多数。输入999,999,999,您将仅触摸exchange(n)
的230个值。粗略地说,您将以{2}的分支因子下降log_2(n)
次(因为n / 4情况被两次应用的n / 2覆盖)。
对于这个具体示例,最好使用map<int, int>
或unordered_map<int, int>
。
您的具体exchange
函数可能如下所示:
std::map<int, int> dp;
int exchange(int n) {
if (n < 12) return n;
auto it = dp.find(n);
if (it != dp.cend()) return it->second;
int val = exchange(n/2) + exchange(n/3) + exchange(n/4);
dp.insert({n, val});
return val;
}
答案 2 :(得分:0)
Vector分配一个内存块,因此有可能找不到可用的内存块(有关内存碎片的信息)。
more是什么,当然,如果您的计算机具有如此大的内存,则在32位系统上每个进程最多可以使用2GB,在64位系统上最多可以使用8TB。