Acwing部分练习:
821. 跳台阶
#include<iostream>
using namespace std;
const int N=20;
int n;
long long a[N];
int main(){
cin>>n;
a[1]=1;
a[2]=2;
if(n>=3){
for(int i=3;i<=n;i++){
a[i]=a[i-1]+a[i-2];
}
}
cout<<a[n]<<endl;
return 0;
}
5292. 跳台阶
#include<iostream>
using namespace std;
const int N=20;
int n,a[N];
int main(){
cin>>n;
a[1]=1,a[2]=2,a[3]=4;
if(n>3){
for(int i=4;i<=n;i++){
a[i]=a[i-1]+a[i-2]+a[i-3];
}
}
cout<<a[n]<<endl;
return 0;
}
92. 递归实现指数型枚举
#include<iostream>
using namespace std;
int n;
int flag[25]; //状态数组:2表示未被选中,1表示已被选中,0表示还未考虑
//枚举顺序:从1到n依次考虑每个数:选/不选
void dfs(int x){ //x表示当前枚举的位置
//选完就终止递归
if(x>n){
for(int i=1;i<=n;i++){
//输出选中的下标
if(flag[i]==1){
cout<<i<<" ";
}
}
cout<<endl;
return;
}
flag[x]=2; //不选
dfs(x+1); //dfs下一个位置
flag[x]=0; //回溯
flag[x]=1; //选
dfs(x+1); //dfs下一个位置
flag[x]=0; //回溯
}
int main(){
cin>>n;
dfs(1);
return 0;
}
93. 递归实现组合型枚举
#include<iostream>
using namespace std;
int n, r;
int ans[25]; //答案数组
//枚举顺序:依次枚举每个位置放哪一个数
//x表示答案数组存储到哪个位置,startt表示下一个位置开始枚举的下标
void dfs(int x,int startt) {
//选完就终止递归
if(x>r){
for(int i=1;i<=r;i++){
printf("%d ",ans[i]);
}
cout<<endl;
return ;
}
for(int i=startt;i<=n;i++){
ans[x]=i; //选数并且存储
dfs(x+1,i+1);//dfs下一个位置并且枚举位置也要下移
ans[x]=0; //回溯
}
}
int main() {
cin>>n>>r;
dfs(1,1);
return 0;
}
洛谷部分练习:
P1192 台阶问题
#include<iostream>
using namespace std;
const int mod=100003;
const int N=1e5+5;
int n,k,a[N];
int main(){
cin>>n>>k;
a[0]=1,a[1]=1;
for(int i=2;i<=n;i++){
for(int j=1;j<=k;j++){
if(i-j>=0)
a[i]=(a[i]+a[i-j])%mod;
}
}
cout<<a[n]%mod<<endl;
return 0;
}
P1706 全排列问题
#include<iostream>
using namespace std;
int n,a[10]; //答案数组:记录选中的数
bool flag[10]; //状态数组:false表示未选中,true表示已选中
//枚举顺序:依次枚举每个位置放哪一个数
void dfs(int x) { //x表示当前枚举的位置
//选完就终止递归
if(x>n){
//输出答案数组
for(int i=1;i<=n;i++){
printf("%5d",a[i]);
}
cout<<endl;
return ;
}
for(int i=1;i<=n;i++){
//找到未选中的数
if(flag[i]==false){
flag[i]=true; //选中
a[x]=i; //选中的数存到答案数组
dfs(x+1); //dfs下一个位置
flag[i]=false;//回溯
a[x]=0; //答案数组置零
}
}
}
int main() {
cin>>n;
dfs(1);
return 0;
}
P1157 组合的输出
#include<iostream>
using namespace std;
int n, r;
int ans[25]; //答案数组
//枚举顺序:依次枚举每个位置放哪一个数
//x表示答案数组存储到哪个位置,startt表示下一个位置开始枚举的下标
void dfs(int x,int startt) {
//选完就终止递归
if(x>r){
for(int i=1;i<=r;i++){
printf("%3d",ans[i]);
}
cout<<endl;
return ;
}
for(int i=startt;i<=n;i++){
ans[x]=i; //选数并且存储
dfs(x+1,i+1);//dfs下一个位置并且枚举位置也要下移
ans[x]=0; //回溯
}
}
int main() {
cin>>n>>r;
dfs(1,1);
return 0;
}
P1036 [NOIP2002 普及组] 选数
#include<iostream>
using namespace std;
int n,k,a[25],ans[25]; //a数组存所给的数,ans数组存答案
long long res=0; //res计数
int isprime(int p){ //判断素数,是素数返回1,不是返回0
if(p==1) return 0;
for(int i=2;i*i<p;i++){
if(p%i==0) return 0;
}
return 1;
}
//枚举顺序:依次枚举每个位置放哪个数
//x表示答案数组存储到哪个位置,startt表示下一个位置开始枚举的下标
void dfs(int x,int startt){
if(x>k){ //选完就终止递归
int sum=0;
for(int i=1;i<=k;i++) sum+=ans[i];//求和
if(isprime(sum)==1) res++; //判断并且计数
return ;
}
for(int i=startt;i<=n;i++){
ans[x]=a[i]; //选数并且存储
dfs(x+1,i+1);//dfs下一个位置并且枚举位置也要下移
ans[x]=0; //回溯
}
}
int main() {
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
dfs(1,1);
cout<<res<<endl;
return 0;
}
B3621 枚举元组
#include<iostream>
using namespace std;
int n,k,a[6];
void dfs(int x){
if(x>n){
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
cout<<endl;
return ;
}
for(int i=1;i<=k;i++){
a[x]=i;
dfs(x+1);
a[x]=0;
}
}
int main() {
cin>>n>>k;
dfs(1);
return 0;
}
B3622 枚举子集
#include<iostream>
using namespace std;
int n,a[15];
void dfs(int x){
if(x>n){
for(int i=1;i<=n;i++){
if(a[i]==1) cout<<"N";
if(a[i]==0) cout<<"Y";
}
cout<<endl;
return ;
}
a[x]=1;
dfs(x+1);
a[x]=0;
dfs(x+1);
}
int main() {
cin>>n;
dfs(1);
return 0;
}
B3623 枚举排列
#include<iostream>
using namespace std;
int n,k,a[15],flag[15];
void dfs(int x){
if(x>k){
for(int i=1;i<=k;i++) cout<<a[i]<<" ";
cout<<endl;
return;
}
for(int i=1;i<=n;i++){
if(flag[i]==0){
flag[i]=1;
a[x]=i;
dfs(x+1);
flag[i]=0;
}
}
}
int main(){
cin>>n>>k;
dfs(1);
return 0;
}