题目
昨天晚上一直写,但是写不出来,今天再重新看了《算法笔记》上的代码,突然有了新的感受。首先根据已知的n和p,得到因子可能出现的范围(包括0),因为vector的因子是升序的,根据题目的要求,从最大值开始进行选择,但是注意一个数字可以出现多次,也可以一次都不出现。这决定了dfs如何转移状态.递归的终止条件很好判断。这也是很暴力的深搜。
#include <bits/stdc++.h>
using namespace std;
vector<int> num, temp, ans;
int n, k, p, maxall=-1;
int cal(int x){
int ans=1;
for(int i=1; i<=p; i++)
ans*=x;
return ans;
}
void init(){
int first=0, temp=cal(first);
while(temp<=n){
num.push_back(first);
first+=1;
temp=cal(first);
}
}
void DFS(int idx, int time, int sum, int all){
if(time==k && sum==n){
if(maxall<all){
ans=temp;
maxall=all;
}
return;
}
if(time>k || sum>n)
return;
if(idx>=1){
temp.push_back(num[idx]);
DFS(idx, time+1, sum+cal(num[idx]), all+num[idx]);
temp.pop_back();
DFS(idx-1, time, sum, all);
}
}
int main()
{
scanf("%d%d%d", &n, &k, &p);
init();
int len=(int)num.size();
DFS(len-1, 0, 0, 0);
if(!ans.size()){
printf("Impossible\n");
} else {
printf("%d = %d^%d", n, ans[0], p);
for(int i=1; i<(int)ans.size(); i++){
printf(" + %d^%d", ans[i], p);
}
printf("\n");
}
return 0;
}