是一道搜索题目,没怎么用剪枝,题目给的时间比较充裕。
在写的过程中出现一个严重的逻辑错误,搜索的范围的出错了。按照我的算法应该是每一次都是从factor递减到1,刚开始写的时候被所谓的“选择和不选择“误导,
最后还是通过单步调试发现的= =
还有值得注意的一点是factor是从sqrt(N)开始的
讲道理按照“选择和不选择“的思路也是可以的,不过要做一点预处理,留个坑来填。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<vector> #include<cmath> using namespace std; int N,K,P; int Pow(int factor) { int ans=1; for(int i=0;i<P;i++) { ans*=factor; } return ans; } bool succ=false; vector<int>ans; vector<int>seq; bool cmp() { int ansSum=0,seqSum=0; for(int i=0;i<ans.size();i++) { ansSum+=ans[i]; } for(int j=0;j<seq.size();j++) { seqSum+=seq[j]; } int ansp=0,seqp=0; while(ansp<ans.size()&&seqp<seq.size()&&ans[ansp]==seq[seqp]){ ansp++; seqp++; } if(ansSum==seqSum) return ans[ansp]<seq[seqp]; return ansSum<seqSum; } void debug() { for(int i=0;i<seq.size();i++) { printf("%d ",seq[i]); } printf(" "); } void dfs(int factor,int sum) { if(seq.size()==K){ if(sum==N){//成功 succ=true; if(cmp()){ ans=seq; } //ans=seq; } return ; } if(sum>=N){ return ; } for(int i=factor;i>=1;i--) { seq.push_back(i); dfs(i,sum+Pow(i)); seq.pop_back(); } } int main() { //freopen("in.txt","r",stdin); scanf("%d%d%d",&N,&K,&P); dfs((int)sqrt(N),0); if(!succ)printf("Impossible "); else { printf("%d =",N); //169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2 //169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2 for(int i=0;i<ans.size();i++) { printf(" %d^%d",ans[i],P); if(i<ans.size()-1)printf(" +"); else printf(" "); } } //getchar(); }