#include <iostream>
using namespace std;
int n,k,sum,ans;
int a[40];
void dfs(int i,int cnt,int s){
if(i==n){
if(cnt==k && s==sum){
ans++;
}
return;
}
dfs(i+1,cnt,s);//不选当前数
dfs(i+1,cnt+1,s+a[i]);//选当前数
}
int main(){
cin>>n>>k>>sum;
for(int i=0;i<n;i++){
cin>>a[i];
}
ans=0;
dfs(0,0,0);
cout<<ans<<endl;
return 0;
}
在递归算法中,通常会考虑某个元素被选择和不被选择两种情况,因此会同时进行这两种情况的递归调用。在这个例子中,对于当前元素,程序会同时考虑选择当前元素和不选择当前元素两种情况,然后分别进行递归调用,以便继续向下搜索可能的解。
因此,在递归调用中,dfs(i + 1, cnt, s) 和 dfs(i + 1, cnt + 1, s + a[i]) 这两个递归调用语句会同时执行,分别对应不选择当前数和选择当前数的情况。这样可以逐步探索所有可能的路径,找到符合条件的解。
#include <iostream>
using namespace std;
int n,k,sum,ans;
int a[40];
bool xuan[110];//标记是否选择了
void dfs(int s,int cnt){
if(s==sum && cnt==k){
ans++;
}
for(int i=0;i<n;i++){
if(!xuan[i]){
xuan[i]=1;
dfs(s+a[i],cnt+1);
xuan[i]=0;
}
}
}
int main(){
cin>>n>>k>>sum;
for(int i=0;i<n;i++){
cin>>a[i];
}
ans=0;
dfs(0,0);
cout<<ans<<endl;
return 0;
}
#include <cstdio>
using namespace std;
int p[15];
int n,sum=0;
bool f;
bool vis[15];
void dfs(int cnt,int s,int st){
if(f){
return;
}
if(cnt==3){
f=true;
return;
}
if(s==sum/3){
dfs(cnt+1,0,0);
return;
}
for(int i=0;i<n;i++){
if(!vis[i]){
vis[i]=true;
dfs(cnt,s+p[i],i+1);
vis[i]=false;
}
}
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&p[i]);
sum+=p[i];
}
if(sum%3 !=0){
printf("no\n");
}else{
dfs(0,0,0);
if(f){
printf("yes\n");
}else{
printf("no\n");
}
}
}
#include <iostream>
using namespace std;
int ans=0;
bool col[10],x1[20],x2[20];//表示列和两条对角线
bool check(int r,int i){
return !col[i]&& !x1[r+i]&& !x2[r-i+8];
}
void dfs(int r){
if(r==8){
ans++;
return;
}
for(int i=0;i<8;i++){
if(check(r,i)){
col[i]=x1[r+i]=x2[r-i+8]=true;
dfs(r+1);
col[i]=x1[r+i]=x2[r-i+8]=false;
}
}
}
int main(){
dfs(0);
cout<<ans<<endl;
return 0;
}