类dfs递归
这个dfs最好有一个树在脑子里面,根节点不设任何东西,他的子节点为第一个位置可能的数,每个节点的子节点为不大于该节点的可能的数,节点的深度等于已经作为候选的数的个数
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
int N, K, P, maxfacsum = 0;
//fac[i]存放i^P,ans存放目前试的序列,res存放最终结果
vector<int> fac, ans, res;
void dfs(int factor, int nowK, int sum, int facsum){
if(nowK == K && sum == N){
if(maxfacsum < facsum){
res = ans;
maxfacsum = facsum;
}
return;
}
if(nowK > K || sum > N)
return;
if(factor > 0){
ans.push_back(factor);
dfs(factor, nowK + 1, sum + fac[factor], facsum + factor);
ans.pop_back();
dfs(factor - 1, nowK, sum, facsum);
}
else
return;
}
int main(){
scanf("%d%d%d", &N, &K, &P);
int i = 0;
while(1){
int facPow = pow(i++, P);
if(facPow <= N)
fac.push_back(facPow);
else
break;
}
dfs(fac.size() - 1, 0, 0, 0);
if(res.empty())
printf("Impossible\n");
else{
printf("%d", N);
for(int j = 0; j < res.size(); j++)
{
if(j == 0)
printf(" = %d^%d", res[j], P);
else
printf(" + %d^%d", res[j], P);
}
printf("\n");
}
return 0;
}
非递归
基本思路就是从大往小的数试,如果当前正在试的数填满所有位置仍比目标总数小,那么再往小的数试就更不可能了(类似于剪枝),这时就要把前一个数减一重新试。(有点小复杂,我刚开始自己绕了好久)
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
int main(){
int n, N, K, P;
scanf("%d%d%d", &n, &K, &P);
N = n;//后面要对n进行操作,所以暂存
//fac[i]存放i^P,ans存放目前试的序列,res存放最终结果
vector<int> fac, ans, res;
int i = 0;
while(1){
int facPow = pow(i++, P);
if(facPow <= N)
fac.push_back(facPow);
else
break;
}
int maxsum = 0;
i = fac.size();
while(1){
//insert
//循环查找当前适合的最大数
while(!(N >= 0 && N <= fac[i - 1] * (K - ans.size())) && i > 2)
i--;
//如果i >= 2而且ans里面尚有空位,则说明找到了可以放入ans的数
if(i >= 2 && ans.size() < K){
ans.push_back(i - 1);
N -= fac[i - 1];
//放入之后如果刚好符合要求,则判断是不是"最优"
if(ans.size() == K && N == 0){
int sum = 0;
for(int j = 0; j < K; j++)
sum += ans[j];
if(sum > maxsum){
maxsum = sum;
res.clear();
for(int j = 0; j < K; j++)
res.push_back(ans[j]);
}
}
}
//否则说明没有找到合适的数
else{
//pop
//如果ans是空的那么说明所有的可能已经试完了
if(ans.empty())
break;
else{
//把ans里的最后一个数减一重新试
N += fac[ans[ans.size() - 1]];
i = ans[ans.size() - 1];
ans.pop_back();
}
}
}
if(res.empty())
printf("Impossible\n");
else{
printf("%d", n);
for(int j = 0; j < res.size(); j++)
{
if(j == 0)
printf(" = %d^%d", res[j], P);
else
printf(" + %d^%d", res[j], P);
}
printf("\n");
}
return 0;
}```