pat a 1103

这道题主要考虑一下怎么写dfs,首先考虑递归出口,如果我们当前要加的是0的p次方,或者相加个数大于k,或者当前总和大于n,那么显然是应该被修剪掉的出口。当当前总和等于n且相加个数等于k时,显然也是一种出口,在这里判断一下当前因子和是不是比以前更大,如果更大了,就记录这条路径。
出口写完了,如果比较熟悉dijsktra+dfs的话,就可以把那个改一下用,两者比较像。现将当前判断的因子加入temp,然后dfs加这个因子的情况,然后把这个因子弹出,dfs不加这个因子的情况。

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

int n,k,p;
vector<int> pownum;
vector<int> path,temp;

int maxfactor=-1;
void dfs(int nowid,int nowfactor,int nowk,int nowsum){
	if(nowid==0||nowk>k||nowsum>n){
		return;
	}
	if(nowsum==n&&nowk==k){
		if(nowfactor>maxfactor){
			path=temp;
			maxfactor=nowfactor;
			return;
		}
	}
	temp.push_back(nowid);
	dfs(nowid,nowfactor+nowid,nowk+1,nowsum+pownum[nowid]);
	temp.pop_back();
	dfs(nowid-1,nowfactor,nowk,nowsum);
}


int main(){
	cin>>n>>k>>p;
	int index=0;
	int temppow=0;
	while(temppow<=n){
		pownum.push_back(temppow);
		index++;
		temppow=pow(index,p);
	}
	int size=pownum.size();
	dfs(size-1,0,0,0);
	if(maxfactor==-1){
		printf("Impossible\n");
	}else{
		printf("%d = ",n);
		for(int i=0;i<path.size();i++){
			if(i!=0){
				printf(" + ");
			}
			printf("%d^%d",path[i],p);
		}
	}	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值