1103素因数分解(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;
}

繰り返し選択

インデックス番号を選択しないことでインデックス+1処理に入ります

#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