1103 Integer Factorization (30分)/DFS专题

PAT习题

在这里插入图片描述

169 5 2

输出:

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

要抛开问题看本质,其实就是简单的可重复选择的选数问题,DFS老经典问题了 不可以害怕!
注意点:
1、预处理不超过n的数,用数组存储 还有要存0,为的就是保持下表与数据对应统一
2、倒着处理fac数组这样就不用再考虑因子顺序问题了
AC代码

#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;
}

BFS经典例题补充

背包问题

#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;
}

选数

不重复选

#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;
}

重复选

index+1处理通过不选择index号数进入

#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;
}

哈哈哈哈 很有成就感 这个寒假比上个暑假可以明显感觉到自己的接受能力更强了嘻嘻嘻 加油鸭!

猜你喜欢

转载自blog.csdn.net/moumoumouwang/article/details/112553108