版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Mr0cheng/article/details/79552041
递归+剪枝,剪纸主要是两个
- 防止K值过大的剪枝,判断另当前后面的数都为1,然后这个和要小于或等于n。(反过来理解是,当前序列所能组成的最小值都比n大的话,直接剪掉)
- 防止P值过小,同时n很大的剪枝,即判断令后面的所有值都为当前这个值,然后这个和要大于或等于n。(反过来理解是,当前序列所能组成的最大值都比n小的话,直接剪掉)
#include<bits/stdc++.h>
using namespace std;
vector<int> ans,temp;
int getSum(vector<int> t){
int cnt=0;
for(vector<int>::iterator it = t.begin();it!=t.end();++it){
cnt+=*it;
}
return cnt;
}
void dfs(int n,int k,int p,int s,int t,int pre){
if(t>k || s>n)return;
if(s==n && t==k){
if(getSum(ans) < getSum(temp)) ans.assign(temp.begin(),temp.end());
return;
}
for(int i=min((int)pow(n-s+1+t-k,1.0/p),pre);i>=1;--i){
if(pow(i,p)+s <= n && pow(i,p)*(k-t)+s>=n)temp.push_back(i),dfs(n,k,p,pow(i,p)+s,t+1,i),temp.pop_back();
}
}
int main(){
int n,k,p;
scanf("%d %d %d",&n,&k,&p);
dfs(n,k,p,0,0,20);
if(ans.empty()){
printf("Impossible");
}else{
printf("%d = ",n);
for(vector<int>::iterator it = ans.begin();it!=ans.end();++it){
if(it==ans.begin())printf("%d^%d",*it,p);
else printf(" + %d^%d",*it,p);
}
}
return 0;
}