返回目录
题意
给定正整数n、k、p,将n表示成k个正整数(可以相同,递减序列)的p次方的和,即n=n1^p+ n2^p+ n3^p+…+ nk^p如果有多种方案,那么选择底数和最大的方案:如果还有多种方案,那么选择底数序列的字典序最大的方案。
样例(可复制)
169 5 2
//output
169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2
169 167 3
//output
Impossible
注意点
- 本题思路如下:①计算得到fac,其中fac最大的数不超过n②从fac[fac.size()-1]的位置从大到小开始选择,每个位置上的数都可能选上或不选,进入递归③每次递归判断当前的情况,是否需要修改ans以及是否sum或nowk超过了条件,根据情况进行return
#include<bits/stdc++.h>
using namespace std;
int n,k,p,maxx=-1;//n为需要分解的数,k为需要分解成几个数,p为几次方,maxx为最大底数和
vector<int> fac,ans,temp; //fac记录0^p,1^p,...i^p<n
int power(int a){
int ans=1;
for(int i=0;i<p;i++)ans*=a;
return ans;
}
void init(){
int i=0,now=0;
while(now<=n){
fac.push_back(now);
now=power(++i);
}
}
void DFS(int index,int nowk,int sum,int facsum){
if(sum==n&&nowk==k){
if(facsum>maxx){
ans=temp;
maxx=facsum;
}
return;
}
if(sum>n||nowk>k)return;
if(index>0){
temp.push_back(index);
DFS(index,nowk+1,sum+fac[index],facsum+index);
temp.pop_back();
DFS(index-1,nowk,sum,facsum);
}
}
int main(){
cin>>n>>k>>p;
init();
DFS(fac.size()-1,0,0,0);
if(maxx==-1)printf("Impossible\n");
else{
printf("%d = %d^%d",n,ans[0],p);
for(int i=1;i<ans.size();i++)printf(" + %d^%d",ans[i],p);
}
return 0;
}