题意:输入N,K,P,问是否存在K个数使得每个数的P次方之和等于N,多种可能输出,所有数的和最大的一种,若还有多种输出非降序的最大的一种。
思路:dfs,减枝。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int MAX_N = 410;
int N, K, P;
vector<int> v;
vector<int> ans;
vector<int> fac;
int msum = -1;
int f_pow(int x, int n) {
int res = 1;
while (n) {
if (n & 1) res *= x;
x = x * x;
n >>= 1;
}
return res;
}
void init() {
int i = 1;
while (f_pow(i, P) <= N) {
fac.push_back(i);
i++;
}
}
void dfs(int num, int k, int p, int ind, int tsum, int le) {
if (k == 0) {
if (num == 0 && msum < tsum) {
ans = v;
msum = tsum;
}
return ;
}
for (int i = ind; i >= 0; i--) {
int t = num - f_pow(fac[i], p);
if (t >= 0) {
v[le] = fac[i];
dfs(t, k-1, p, i, tsum+fac[i], le+1);
}
}
return ;
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d %d %d", &N, &K, &P);
init();
v.resize(K);
dfs(N, K, P, fac.size()-1, 0, 0);
if (msum != -1) {
printf("%d = ", N);
for (int i = 0; i < K; i++) {
if (i > 0) printf(" + ");
printf("%d^%d", ans[i], P);
}
} else {
printf("Impossible\n");
}
return 0;
}