利用dfs来找n
的因子。注意从最大的因子开始找,避免了有多解时找题目中要求的"the largest factor sequence"。
对不可能的路径进行剪枝:1.剩余值remain
小于零、2.剩余值大于零而剩余因子数(dfs本地变量k
)为零。
其中,remain
是剩余要加出来的值,k
是还能添加的因子个数,last
是上一个因子的值,下一个因子只能小于等于上一个因子。
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
int n, k, p;
vector<int> res;
int sum = 0;
int getSum(vector<int> &res) {
int s = 0;
for (int e : res) {
s += e;
}
return s;
}
vector<int> temp;
void dfs(int remain, int k, int last) {
if (k == 0) {
if (remain == 0) {
int s = getSum(temp);
if (s > sum) {
sum = s;
res = temp;
}
}
return;
}
if (remain <= 0)
return;
for (int i = last; i > 0; i--) {
int nextRemain = remain - pow(i, p);
if (nextRemain < 0) {
continue;
}
temp.push_back(i);
dfs(nextRemain, k - 1, i);
temp.pop_back();
}
}
int main() {
cin >> n >> k >> p;
int startFactor = sqrt(n);
dfs(n, k, startFactor);
if (res.empty()) {
cout << "Impossible" << endl;
}
else {
cout << n << " = ";
for (int i = 0; i < k; i++) {
if (i != 0)
cout << " + ";
cout << res[i] << "^" << p;
}
}
}
二刷:
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int n, k, p;
vector<int> res;
int sum;
int getSum(vector<int> &v) {
int sum = 0;
for (int e : v) {
sum += e;
}
return sum;
}
void dfs(int remain, int curFactor, int k, vector<int> &factors) {
if (remain == 0 && k == 0) {
int curSum = getSum(factors);
if (curSum > sum) {
res = factors;
sum = curSum;
}
return;
}
if (remain <= 0 || k == 0) { //当前路径已经不可能满足要求,剪枝
return;
}
for (int i = curFactor; i >= 1; i--) {
factors.push_back(i);
dfs(remain - pow(i, p), i, k - 1, factors);
factors.pop_back();
}
}
int main() {
cin >> n >> k >> p;
vector<int> tmp;
dfs(n, n, k, tmp);
if (res.empty()) {
cout << "Impossible";
return 0;
}
printf("%d = ", n);
for (int i = 0; i < res.size(); i++) {
if (i != 0) {
printf(" + ");
}
printf("%d^%d", res[i], p);
}
}