88888888y

导航

 

题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1440

题目简述:将n划分成k份,问有多少种不同的分法

思路:深搜剪枝

一个个找再对比时间一定会超

何不想一下,既然要不同的分法(顺序无用),那就给他规定一个顺序,比如递增,那样就可以不考虑重复;

那么,按照递增来就可以开始剪枝了

1:下界

由于是递增序列,所以下界就是这一组数列的上一个数,即a[s-1];

2:上界

为保证递增序列,即之后的每个数都比上一个数值大,那么后面的每个数都不可能超过余下数字的平均值

所以上界就是余下的数字除以剩余的划分步骤,即m/(k-s+1)

上代码

#include<bits/stdc++.h>
using namespace std;
int n,k,a[201],ans=0;
void dfs(int m,int s){//搜索
	if(s==k){//步数已经达到了
		if(m>=a[s-1]){//达成递增效果,也就是这个方案可行且没有重复
			ans++;//划分数+1
		}
		return;//再见
	}
	int i;
	for(i=a[s-1];i<=m/(k-s+1);++i){//上下界剪枝
		a[s]=i;
		m-=i;
		dfs(m,s+1);
		m+=i;//记得回溯
	}
}
int main(){
	scanf("%d%d",&n,&k);
	a[0]=1;
	dfs(n,1);//开搜
	printf("%d",ans);
	return 0;
}

题目总结:本次运用到了“上下界剪枝”这一知识点
合理运用剪枝,保证时间不爆,是这道题的亮点,也是难点
posted on 2022-03-13 10:08  88888888y  阅读(45)  评论(0)    收藏  举报