该题还不错~。
题意:给定N、K、P,使得可以分解成N = n1^P + … nk^P的形式,如果可以,输出sum(ni)最大的划分,如果sum一样,输出序列较大的那个。否则输出Impossible。
dfs枚举,为了防止超时,这里要预先将从1开始的i^p的值存储在factor数组中,直到i^p>n。然后dfs深度优先搜索,相当于把问题一步步分解,即若第一个因子是n1,则接下来我们要判断N-n1^p、k-1是否可行。同时存储当前因子的总和sum,要取sum最大的;还有上一次相加的因子的索引last,因为因子要从大到小输出,所以后一个不能大于前一个因子。
#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <cmath> using namespace std; /* 其实可以预先把i^p<n的i都存储起来 */ const int maxn=405; int res[maxn]; int ans[maxn]; int factor[maxn]; int fidx=0; int maxsum=0; bool flag=false; int n,k,p; /* num为当前的总和 cnt为还剩几个i^p项,即当前的k sum为各因子的总和,因为要取和最大的 last为上一个因子的索引,因为要保证因子从大到小输出, 所以dfs后一个因子在factor中的索引不能大于上一个 */ void dfs(int num,int cnt,int sum,int last){ if(num==0&&cnt==0){ if(sum>maxsum){ flag=true; for(int i=1;i<=k;i++) ans[i]=res[i]; maxsum=sum; } return; } else if(cnt==0) return; for(int i=min(fidx-1,last);i>=0;i--){ int left=num-factor[i]; if(left>=cnt-1){ res[cnt]=i+1; dfs(left,cnt-1,sum+i+1,i); } } } int main() { scanf("%d %d %d",&n,&k,&p); int tmp=1; fidx=0; //预先存储i^p<=n的i while(tmp<=n){ factor[fidx]=tmp; fidx++; tmp=pow(fidx+1,p); } int cnt=0; int last=fidx-1; dfs(n,k,0,last); if(flag){ printf("%d =",n); for(int i=k;i>=2;i--){ printf(" %d^%d +",ans[i],p); } printf(" %d^%d",ans[1],p); } else{ printf("Impossible"); } return 0; }