#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
using namespace std;
const int maxn=400;
int n,k,p,num;
int maxSum=0;
int a[maxn];
vector<int> temp;
vector<int> ans;
//也有可能出现maxSum是一样的解:从大到小执行可以直接选择最大的
//因为后续遍历到小的不会发生最大值的替换
//:这也是为什么从小到大(index从0开始执行)出错的原因
void DFS(int index,int nowk,int nowsum,int nowsqu){
if(nowk==k){
if(nowsum>maxSum&&nowsqu==n){
maxSum=nowsum;
ans=temp;
}
return;
}
if(index==0 || nowk>k || nowsqu>n){
return;
}
//选择index数
if((nowsqu+a[index])<=n){//剪枝
temp.push_back(index);
DFS(index,nowk+1,nowsum+index,nowsqu+a[index]);
temp.pop_back();//Delete last element
}
//不选择index数
DFS(index-1,nowk,nowsum,nowsqu);
}
int main()
{
scanf("%d %d %d",&n,&k,&p);
//对数组a进行预处理:里面存放从0到i的p次方,直到a[i]>n为止
for(num=1;pow(num,p)<=n;num++){
a[num]=pow(num,p);
}
int c=num-1;
DFS(c,0,0,0);//保证后续的ans是从大到小存储的
int size=ans.size();
if(size>0){
//注意输出格式=和+两边有空格。。。。
printf("%d = ",n);
for(int i=0;i<size;i++){
if(i!=0)printf(" + ");
printf("%d^%d",ans[i],p);
}
}else{
printf("Impossible\n");
}
return 0;
}
注意有个问题是:
题目要求的
If there is a tie, the largest factor sequence must be chosen -- sequence { a1,a2,⋯,aK } is said to be larger than { b1,b2,⋯,bK } if there exists 1≤L≤K such that ai=bi for i<L and aL>bL.
tie:平局:也就是如果出现多解的情况下,1先判断选出sum最大的(选中的所有factor之和)2.如果sum最大的还有多解,那么按照上面的方法选择一个最优解(算法笔记中称为:选择底数序列的字典序最大的方案)
所以要按照从大到小来执行