題目鏈接:傳送門
思路:因爲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;
}