【1103】Integer Factorization (DFS)

简介: (1)开一个vector数组fac存0^ p ,1^ p… i ^ p.(2)DFS:分叉口:利用DFS对fac[index]进行选择,有“选”与“不选”两种选择,如果不选,则把问题转化为对fac[index]进行选择;如果选择,由于每个数字可以重复选择即下一次还能选择fac[index]。递归边界:2个return,第一个满足sum == N且nowK==

1.题目

https://pintia.cn/problem-sets/994805342720868352/problems/994805364711604224

给出正整数N,K,P,求N由K个整数的分别的P次方的和的情况,如果有多种情况则选择底数和最大的方案。

举例:169 5 2

输出:159=6^ 2 + 6^ 2+6^ 2+6^ 2+5^ 2

2.思路

(1)开一个vector数组fac存0^ p ,1^ p… i ^ p.

(2)DFS:

分叉口:利用DFS对fac[index]进行选择,有“选”与“不选”两种选择,如果不选,则把问题转化为对fac[index]进行选择;如果选择,由于每个数字可以重复选择即下一次还能选择fac[index]。

递归边界:2个return,第一个满足sum == N且nowK==k成立时则找到一个满足条件的序列——记住为了找出多方案的最优情况,需要判断底数之和facSum是否比一个全局记录的最大底数之和maxFacSum更大,更大则更新。

第二个return是底数之和大于N或底数个数大于K就不阔能出答案了,马上return。

(3)为了让结果能够保证字典序大的序列优先被选中,让index从大到小递减来遍历,这样总是能先选中fac中较大的数。

3.代码

#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=30;
vector<int>fac,ans,temp;//fac记录i^p
int n,k,p,maxFacSum=-1;
int pinfang(int x){
  int ans=1;
  for(int i=0;i<p;i++){
    ans*=x;
  }
  return ans;
}
//init函数预处理fac数组,注意把0也存进去
void init(){
  int i=0,temp1=0;
  while(temp1<=n){
    fac.push_back(temp1);
    temp1=pinfang(++i);
  }
}
void DFS(int index,int nowK,int sum,int facSum){
  if(sum==n&&nowK==k){//找到一个满足的序列
    if(facSum>maxFacSum){
      ans=temp;
      maxFacSum=facSum;//更新最大底数之和
    }
    return;
  }
  if(sum>n||nowK>k)
    return;//不会产生答案,直接返回
  if(index-1>=0){//fac[0]不需要选择,从大到小
    temp.push_back(index);
    DFS(index,nowK+1,sum+fac[index],facSum+index);
    temp.pop_back();
    DFS(index-1,nowK,sum,facSum);
  }
}
int main(){
   scanf("%d%d%d",&n,&k,&p);
   init();
   DFS(fac.size()-1,0,0,0);//从fac的最后一位开始往前搜索
   if(maxFacSum==-1)
     printf("Impossible\n");
   else{
    printf("%d = %d^%d",n,ans[0],p);
    for(int i=1;i<ans.size();i++)
      printf(" + %d^%d",ans[i],p);
   }
  system("pause");
}

4.注意

(1)多方案时判断是否更优的做法的时间复杂度最好是O(1),否则容易超时。因此必须在DFS的参数中记录当前底数之和facSum,避免在找到一组解时计算序列的底数之和。

(2)和(1)一样,不要在找到一组解时才判断vector型的temp和ans数组的字典序,而应该让index从大到小进行选择,这样fac[index]大的就会相对早地被选中。

相关文章
|
8月前
|
C++
E. Generate a String(典:贪心+动态规划)
E. Generate a String(典:贪心+动态规划)
Biggest Number (DFS+剪枝)
Biggest Number (DFS+剪枝)
45 0
|
Java
hdu1016 Prime Ring Problem【素数环问题(经典dfs)】
hdu1016 Prime Ring Problem【素数环问题(经典dfs)】
69 0
Find The Multiple(dfs和bfs都可)
Find The Multiple(dfs和bfs都可)
32 0
|
机器学习/深度学习
CF1552A Subsequence Permutation(string排序大法)
CF1552A Subsequence Permutation(string排序大法)
42 0
LeetCode Contest 186 5392. 分割字符串的最大得分 Maximum Score After Splitting a String
LeetCode Contest 186 5392. 分割字符串的最大得分 Maximum Score After Splitting a String
codeforces1244——D.Paint the Tree(dfs)
codeforces1244——D.Paint the Tree(dfs)
90 0
2019EC Final E-Flow(贪心 dfs)
2019EC Final E-Flow(贪心 dfs)
102 0
Biggest Number深搜
You can start from any square, walk in the maze, and finally stop at some square. Each step, you may only walk into one of the four neighbouring squares (up, down, left, right) and you cannot walk into obstacles or walk into a square more than once.
119 0
Biggest Number深搜
【1103】Integer Factorization (30分)【DFS】
【1103】Integer Factorization (30分)【DFS】 【1103】Integer Factorization (30分)【DFS】
95 0