PAT 1103 Integer Factorization
这一题是让找一个数由K个数,每一个数的P次幂,相加之和等于N。
如果有多种情况,就保存底数之和最大的那一种情况,如果底数之和一样,那么就找序列值最大的情况。
这一题最重要的就是看出来,要先保存从1的P次幂到。。。小于N的所有次幂的情况。然后用dfs来枚举所有符合条件的组合情况,
要注意从高位往低位遍历,因为题目上要求的数的序列和是非递增序列。
弄清楚题意后,就是正常的dfs枚举,每次有选与不选两种情况。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <unordered_map>
#include <limits.h>
#include <queue>
#include <string.h>
#include <stack>
using namespace std;
int N;
int P;
int K;
vector<int> n;
vector<int> endans;
vector<int> total;
int maxx=-1;
void dfs(int index,int ans,int sum,int cnt)
{if(cnt>K){return;}if(ans==N){//说明符合条件if(cnt==K){if(sum>maxx){maxx=sum;endans=total;} }return ;}if(ans>N||index<0){return;}if(ans+n[index]<=N){//说明可以选 total.push_back(index+1);dfs(index,ans+n[index],sum+index+1,cnt+1);total.pop_back();}dfs(index-1,ans,sum,cnt);}
int main()
{//ios::sync_with_stdio(0),cin.tie(0),cout.tie(cin>>N>>K>>P;for(int i=1;i<=N;i++){int x=(int)pow(i,P);if(x>N){break;}n.push_back(x);}//看怎么找K个数dfs(n.size()-1,0,0,0);if(maxx==-1){cout<<"Impossible";cout<<endl;return 0;} cout<<N<<" = ";for(int i=0;i<endans.size();i++){if(i!=0)cout<<" + ";cout<<endans[i]<<"^"<<P;}cout<<endl;return 0;}
在写的过程中,之前有一点是测试点5一直不过,原因是在算:
for(int i=1;i<=N;i++){int x=(int)pow(i,P);if(x>N){break;}n.push_back(x);}
是i<N.而不是i<=N,测试点5就不过了。。。。
总结:这一题是dfs选与不选的典型题目,关键在于弄清楚题意,看出来是用dfs,并把可能的项数提前放到数组中,方便dfs遍历所有情况。
在写题的时候一定要注意边界条件。。