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

博客围绕一道简单的dfs题展开,给出题目链接。强调解题需剪枝,否则会超时。介绍用dfs(a,u,num)表示上一个数为a,已搜索完a个数且当前和为num。还说明了剪枝思路,即根据剩余层数和数的大小关系判断是否继续递归,并给出最终代码的转载链接。

题目链接

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

解题思路

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


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

 1 #include<iostream>
 2 using namespace std;
 3 int n,k,a;
 4 long long ans;
 5 void dfs(int a,int u,int now){
 6     if(now>n) return;
 7     if(u>k) return; 
 8     if(u==k){
 9         if(now==n) ans++;
10         return;
11     }
12     for(int i=a;i<=n;i++){
13         dfs(i,u+1,now+i);
14     }
15 }
16 int main(){
17     cin>>n>>k;
18     dfs(1,0,0);
19     cout<<ans;
20     return 0;
21 }
未剪枝代码

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

最终代码

 1 #include<iostream>
 2 using namespace std;
 3 int n,k,a;
 4 long long ans;
 5 void dfs(int a,int u,int now){
 6     if(now>n) return;//边界 
 7     if(u>k) return; 
 8     if(u==k){
 9         if(now==n) ans++;
10         return;
11     }
12     for(int i=a;now+i*(k-u)<=n;i++){//剪枝 
13         dfs(i,u+1,now+i);
14     }
15 }
16 int main(){
17     cin>>n>>k;
18     dfs(1,0,0);
19     cout<<ans;
20     return 0;
21 }

//NOIP2001提高组 t2

 

转载于:https://www.cnblogs.com/yinyuqin/p/10883639.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值