1103 Integer Factorization (30 points)/DFS topic

PAT exercises

Insert picture description here

169 5 2

Output:

169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2

To put aside the problem and look at the essence, it is actually a simple and repeatable selection problem. DFS is an old classic problem. Don't be afraid!
Points to note:
1. Preprocess the number that does not exceed n, use an array to store it and store 0, in order to keep the following table and the data corresponding to each other,
2. Process the fac array backwards so that you don’t need to consider the order of factors
AC code

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 100010;

int n, k, p, maxSum = -1;
vector<int> fac, ans, temp;

int pow(int i)
{
    
    
	int sum =1;
	for(int j = 0; j < p; j++)
	{
    
    
		sum *= i; 
	}
	return sum;
}

//预处理 把不超过n的数字提前存放进去
void init()
{
    
    
	int i = 0, temp = 0;
	while(temp <= n)
	{
    
    
		fac.push_back(temp);
		temp = pow(++i);
	}
}
int num;
int flag[maxn];
//int Facsum因子平方和 int sum因子和 
void DFS(int index, int nowk, int Facsum, int sum)
{
    
    
	if(index == 0 || nowk > k || Facsum > n) return;//不选fac[0]
	// if(nowk > k || Facsum > n) return;
	if(nowk == k && Facsum == n)
	{
    
    
		if(sum > maxSum)
		{
    
    
			maxSum = sum;
			ans = temp;
		}
		return;
	}
		//可重复选择当前的 但是不加入temp
		temp.push_back(index);
		DFS(index,nowk + 1,Facsum + fac[index], sum + index);
		temp.pop_back();
		//不选index号数
		DFS(index - 1, nowk, Facsum, sum);
}
int main()
{
    
    
	cin >> n >> k >> p;
	init();
	DFS(fac.size()-1,0,0,0);
	if(maxSum == -1) cout << "Impossible";
	else
	{
    
    
		printf ("%d = %d^%d", n, ans[0] ,p);
		for(int i = 1; i < ans.size(); i++)
		{
    
    
			printf(" + %d^%d",ans[i],p);
		}
	}
	return 0;
}

Supplement to BFS classic example

Backpack problem

#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 100010;
//背包问题
int n, v, maxvalue = 0;//n件商品 最大价值
int w[maxn],c[maxn];

//void DFS(int index,int sumw, int sumc)
// {
    
    
// 	if(n == index)
// 	{
    
    
// 		if(sumw <= v && sumc > maxvalue)
// 		{
    
    
// 			maxvalue = sumc;
// 		}
// 		return ;
// 	}
// 	DFS(index + 1, sumw, sumc);
// 	DFS(index + 1, sumw + w[index], sumc + c[index]);
// }
//剪枝
void DFS(int index,int sumw, int sumc)
{
    
    
	if(n == index)	return ;

	DFS(index + 1, sumw, sumc);

	if(sumw + w[index]<= v)
		{
    
    
			if(sumc + c[index] > maxvalue)
			 maxvalue = sumc + c[index];
		}
	DFS(index + 1, sumw + w[index], sumc + c[index]); //选index
}

int main()
{
    
    
	cin >> n >> v;
	for(int i = 0; i < n; i++)
	{
    
    
		cin >> w[i];
	}
	for(int i = 0; i < n; i++)
	{
    
    
		cin >> c[i];
	}
	DFS(0, 0, 0);
	cout << maxvalue;
	return 0;
}

Choose the number

Do not repeat

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 100010;
//从n中选择k个数 满足k个数之和为x并且平方和最大
vector<int> temp,ans;
int n,k,x;
int A[maxn], maxsumseq = -1;

void DFS(int index, int nowk,int sum, int sumseq)
{
    
    
	if(nowk == k && sum == x)
	{
    
    
		if(sumseq > maxsumseq)
		{
    
    
			maxsumseq = sumseq;
			ans = temp;
		}
		return;
	}
	if(index > n||nowk > k|| sum > x) return;
	temp.push_back(A[index]);
	DFS(index + 1,nowk + 1,sum + A[index], sumseq + A[index] * A[index]);
	temp.pop_back();
	DFS(index + 1,nowk,sum,sumseq);
}
int main()
{
    
    
	cin >> n >> k >> x;
	for(int i = 0; i < n; i++)
	{
    
    
		cin >> A[i];
	}
	DFS(0, 0, 0,0);
	for(vector<int>::iterator it = ans.begin(); it != ans.end(); it++)
	{
    
    
		cout << *it << " ";
	}
	return 0;
}

Repeated selection

Index+1 processing is entered by not selecting the index number

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 100010;
//从n中可重复选择k个数 满足k个数之和为x
vector<int> temp,ans;
int n,k,x;
int A[maxn], maxsumseq = -1;

void DFS(int index, int nowk,int sum, int sumseq)
{
    
    
	if(nowk == k && sum == x)
	{
    
    
		if(sumseq > maxsumseq)
		{
    
    
			maxsumseq = sumseq;
			ans = temp;
		}
		return;
	}
	if(index > n||nowk > k|| sum > x) return;
	temp.push_back(A[index]);
	DFS(index, nowk + 1,sum + A[index], sumseq + A[index] * A[index]);
	temp.pop_back();
	DFS(index + 1,nowk,sum,sumseq);
}
int main()
{
    
    
	cin >> n >> k >> x;
	for(int i = 0; i < n; i++)
	{
    
    
		cin >> A[i];
	}
	DFS(0, 0, 0,0);
	for(vector<int>::iterator it = ans.begin(); it != ans.end(); it++)
	{
    
    
		cout << *it << " ";
	}
	return 0;
}

Hahahahaha, I have a sense of accomplishment. This winter vacation can obviously feel that I am more receptive than last summer. Hehehe Come on!

Guess you like

Origin blog.csdn.net/moumoumouwang/article/details/112553108