题意: 给定N, K, P; 将N表示成K个正整数的P次方的和,如果有多中方案,那么选择n1 + .. nk的最大的方案;
如果还有多种方案,选择序列的字典序最大的方案;
字典序最大的过程在从大往小遍历的过程中已经自动实现
#include<cstdio>
#include<math.h>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 410;
vector<int> temp,ans;//temp存储临时方案,ans存储最优方案
vector<int> fac;
int sum = 0;
int n,p,k;
//计算x^p
int power(int x){
int r = 1;
for(int i = 1;i<=p;i++){
r = r*x;
}
return r;
}
//递减
bool cmp(int a,int b){
return a>b;
}
void init(){
int i = 1,temp = 0;
while(temp<=n){
fac.push_back(i);
temp = power(++i);
}
return;
}
void DFS(int step,int sumSqu,int facSum,int index){
if(step==k&&sumSqu==n){//已经完成k轮搜索
if(facSum>sum){
ans = temp;
sum = facSum;
}
return;
}
else if(step==k||sumSqu>n) return;
else {//再次搜索的前提
for(int i = index;i<fac.size();i++){
temp.push_back(fac[i]);
DFS(step+1,sumSqu+power(fac[i]),facSum+fac[i],i);
temp.pop_back();
}
}
return;
}
int main(){
scanf("%d %d %d",&n,&k,&p);
init();
sort(fac.begin(),fac.end(),cmp);
DFS(0,0,0,0);
if(sum==0) printf("Impossible
");
else{
printf("%d =",n);
for(int i = 0;i<k;i++){
printf(" %d^%d",ans[i],p);
if(i!=k-1) printf(" +");
}
}
return 0;
}