我正在尝试使用动态编程范例解决在线评判中的某个问题。我写了一个函数,它记住了较小的子问题的结果。但是这个函数在一次运行中将被称为 t次。因此,当函数调用自身时,我希望保留" Memory" ,但是当从驱动程序调用它时,我想要重置向量。我怎么做?我认为拥有一个全局向量并在每次调用驱动程序后重置它是可能的,但正如我从书籍和堆栈溢出中学到的那样"错误的编程风格" 。那么这个问题的解决方案是什么?下面是代码:
class mem{
public:
bool mike_win;
bool written;
};
bool calc(int a){
static vector<mem> memory(a);
if( a == 1){
return false;
}
if(memory[a-1].written == true){
return (!(memory[a-1].mike_win))
}
vector<int> div_list = divis(a);
//^^ divis is a function which takes a number and returns
//all its divisors in descending order in a vector<int>
for(vector<int>::iterator i = div_list.begin();i != div_list.end();i++){
if ( ! ( calc( a / (*i) ))){
memory[a-1].written = true;
memory[a-1].mike_win = true;
return true;
}
}
if(calc(a-1 ) == false){
memory[a-1].written = true;
memory[a-1].mike_win = true;
return true;
}
else{
memory[a-1].written = false;
memory[a-1].mike_win = false;
return false;
}
}
下面是question.的链接和继承函数divis:
vector<int> divis(int a){
vector<int> div_list(int a )
if(a==2){
return div_list;
}
int k = sqrt(a);
for(int i=2;i<=k;i++){
if(!(a%i)){
div_list.push_back(i);
div_list.push_back(a/i);
}
}
sort(div_list.rbegin(),div_list.rend());
div_list.erase(unique(div_list.begin(),div_list.end()),div_list.end());
return div_list;
}
答案 0 :(得分:3)
我认为我这样做的方法是创建两个calc
的重载:on只需int
作为参数,另一个需要int
和引用vector<int>
。这样,用户将调用第一个重载,它将创建用于记忆的临时向量,并将其传递给第二个函数,该函数在递归时传递引用。有点像这样:
bool calc(int a, vector<int>& memory)
{
// Do your stuff here
// Instead of calling it as calc( a / (*i) ), just call
// it as calc( a / (*i) , memory )
}
bool calc(int a)
{
vector<int> memory(a);
calc(a, memory);
}
这样,您就可以避免在算法的核心进行任何类型的簿记,以确定是否清除向量;它将在第一次调用返回后自动完成。