P1025 [NOIP2001 提高组] 数的划分
题目链接
题意:求n个能够划分成k个数有几种做法,要求不能有重复的
解题报告:
(方法1)搜索dfs:自上而下的升序
剪枝前:
注意:
return;是返回到dfs(,,);该行的末尾,之后继续执行下一层循环
#include<iostream>
using namespace std;
int n,k;
int ans;
void dfs(int index,int u,int now)
{
if(u>k)return ;
if(now>n) return;
if(u==k)
{
if(now==n)ans++;
return;
}
for(int i=index;i<=n;i++)
{
dfs(i,u+1,now+i);
}
}
int main(){
cin>>n>>k;
dfs(1,0,0);
cout<<ans;
return 0;
}
但是如果n很大,需要执行n2级运算,因此需要剪枝
剪枝后:
#include<iostream>
using namespace std;
int n,k;
int ans;
void dfs(int index,int u,int now)
{
if(u>k)return ;
if(now>n) return;
if(u==k)
{
if(now==n)ans++;
return;
}
for(int i=index;now+(k-u)*i<=n;i++)//jian zhi
{
dfs(i,u+1,now+i);
}
}
int main(){
cin>>n>>k;
dfs(1,0,0);
cout<<ans;
return 0;
}
(方法二)回溯法:自上而下的回溯
#include<iostream>
using namespace std;
int n,k;
int ans=0;
void huisu(int n,int k,int index)
{
if(k==0)
{
if(n==0) ans++;
return ;
}
for(int i=index;i*k<=n;i++)
{
huisu(n-i,k-1,i);
}
}
int main(){
cin>>n>>k;
huisu(n,k,1);
cout<<ans;
return 0;
}