洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)

时间:2023-03-09 17:31:50
洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)

题目链接

https://www.luogu.org/problemnew/show/P1025

解题思路

一道简单的dfs题,但是需要剪枝,否则会TLE。

洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)


我们用dfs(a,u,num)来表示上一个数为a,已经搜索完了a个数,现在的和是num。

 #include<iostream>
using namespace std;
int n,k,a;
long long ans;
void dfs(int a,int u,int now){
if(now>n) return;
if(u>k) return;
if(u==k){
if(now==n) ans++;
return;
}
for(int i=a;i<=n;i++){
dfs(i,u+,now+i);
}
}
int main(){
cin>>n>>k;
dfs(,,);
cout<<ans;
return ;
}

未剪枝代码


剪枝:现在搜索完u层了,那么还剩下k-u层,因为后一个数一定大于等于前一个数,所以i从a开始,而且后边的数一定>=i,所以i*(k-u)表示后边的数的最小和,如果现在的和加上后面的最小和已经大于n了,直接不去继续递归了。

最终代码

 #include<iostream>
using namespace std;
int n,k,a;
long long ans;
void dfs(int a,int u,int now){
if(now>n) return;//边界
if(u>k) return;
if(u==k){
if(now==n) ans++;
return;
}
for(int i=a;now+i*(k-u)<=n;i++){//剪枝
dfs(i,u+,now+i);
}
}
int main(){
cin>>n>>k;
dfs(,,);
cout<<ans;
return ;
}

//NOIP2001提高组 t2