这道题主要考虑一下怎么写dfs,首先考虑递归出口,如果我们当前要加的是0的p次方,或者相加个数大于k,或者当前总和大于n,那么显然是应该被修剪掉的出口。当当前总和等于n且相加个数等于k时,显然也是一种出口,在这里判断一下当前因子和是不是比以前更大,如果更大了,就记录这条路径。
出口写完了,如果比较熟悉dijsktra+dfs的话,就可以把那个改一下用,两者比较像。现将当前判断的因子加入temp,然后dfs加这个因子的情况,然后把这个因子弹出,dfs不加这个因子的情况。
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int n,k,p;
vector<int> pownum;
vector<int> path,temp;
int maxfactor=-1;
void dfs(int nowid,int nowfactor,int nowk,int nowsum){
if(nowid==0||nowk>k||nowsum>n){
return;
}
if(nowsum==n&&nowk==k){
if(nowfactor>maxfactor){
path=temp;
maxfactor=nowfactor;
return;
}
}
temp.push_back(nowid);
dfs(nowid,nowfactor+nowid,nowk+1,nowsum+pownum[nowid]);
temp.pop_back();
dfs(nowid-1,nowfactor,nowk,nowsum);
}
int main(){
cin>>n>>k>>p;
int index=0;
int temppow=0;
while(temppow<=n){
pownum.push_back(temppow);
index++;
temppow=pow(index,p);
}
int size=pownum.size();
dfs(size-1,0,0,0);
if(maxfactor==-1){
printf("Impossible\n");
}else{
printf("%d = ",n);
for(int i=0;i<path.size();i++){
if(i!=0){
printf(" + ");
}
printf("%d^%d",path[i],p);
}
}
return 0;
}