题目链接1103 Integer Factorization
题意
求k个数的p次幂之和等于N。答案可能有多种,输出k个数之和最大的那种,若和最大则输出字典序最大的。
解题思路
一开始自己想的是暴力搜索,从n开始往下减到1,通过剪枝降低时间复杂度,从大数开始搜索,可以保证字典序是最大的,然后在比较各位数之和,但是写出来依然超时。网上搜了一些博客解决了问题。
因为a[i]都要大于0,n最大为400,所以不必要从n开始往下枚举,只需枚举a[i] 从1开始递增,使得a[i]^p <= n, 将1-i的P次幂存储到vector中,然后dfs搜索。
对于每种可能选择,或者不选。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
const int maxn = 500;
int n, k, p;
vector<int> ans, v, vt;
int maxSum = 0;
int Pw(int x);
int getSum();
void init();
void dfs(int index, int step, int val);
int main(int argc, char** argv) {
scanf("%d%d%d", &n, &k, &p);
init();
dfs(v.size() - 1, 0, n);
if (ans.size() == 0)
printf("Impossible\n");
else {
printf("%d = ", n);
for (int i = 0; i < k; i++) {
if (i == 0) {
printf("%d^%d", ans[i], p);
} else {
printf(" + %d^%d", ans[i], p);
}
}
}
return 0;
}
/**
n 分解 最大只能分解为 i^p <= n,只需要将1 - i的p次幂存入数组中,从中选择
*/
void init() {
v.push_back(0);
for (int i = 1; Pw(i) <= n; i++) {
v.push_back(Pw(i));
}
}
int Pw(int x) {
int sum = 1;
for (int i = 0; i < p; i++) {
sum *= x;
}
return sum;
}
void dfs(int index, int step, int val) {
if (step == k) {
if (val == 0) {
int sum = getSum();
if (sum > maxSum) {
maxSum = sum;
ans = vt;
}
}
return ;
}
if (val <= 0 || index <= 0)
return ;
vt.push_back(index);
dfs(index, step + 1, val - v[index]);
vt.pop_back();
dfs(index - 1, step, val);
}
int getSum() {
int sum = 0;
for (int i = 0; i < vt.size(); i++) {
sum += vt[i];
}
return sum;
}