题目链接:传送门
思路:因为N的大小只有400,直接暴力即可,应为序列是非增序,所以每层递归从最大可能值递归到1,顺便加个减支条件:如果后面元素全取最大值仍不满足条件则不用再继续搜索了。顺便加了个快速幂。
不过dfs算复杂度不方便,我做这题时不清楚会不会超时,然后就做了挺久的。。似乎可以数学证明复杂度不会超时(口胡)。。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 405;
typedef long long ll;
int a[maxn] , b[maxn];
//bool vis[maxn][maxn];
int n , k , p , cnt , ans;
ll mpow(ll a , ll b) {
ll res = 1;
while(b--) {
res *= a;
}
return res;
}
bool dfs(int sum , int num , int d) {
int i , tag = 0;
ll t;
for(i = num ; i >= 1 ; i--) {
t = pow(i , p);
if(sum < t)continue;
if(t * (k - d + 1) < sum)break;
cnt += i;
a[d] = i;
if(d == k) {
if(sum == t) {
if(cnt > ans) {
for(int j = 1 ;j <= n ; j++)b[j] = a[j];
ans = cnt;
}
cnt -= i;
return true;
}
}
else {
if(dfs(sum - t , i , d + 1)) {
tag = 1;
}
}
cnt -= i;
}
if(!tag)return false;
else return true;
}
int main()
{
ios::sync_with_stdio(0);
cin >> n >> k >> p;
bool flag = 0;
cnt = ans = 0;
flag = dfs(n , n / k + 1 , 1);
if(!flag) cout << "Impossible\n";
else {
cout << n << " = " << b[1] << "^" << p;
for(int i = 2 ; i <= k ; i++) {
cout << " + " << b[i] << "^" << p;
}
cout << "\n";
}
return 0;
}