递归小结

思路 :

用递归的方法,判断到an的时候有两种情况

(1){an}是k个集合中的一个,那么这时候的情况等于s(n-1,k-1)

(2){an}不是k个集合中的一个,也就是说an和别的物品一起放在一个盒子,此时等于有k个盒子n-1个物品的情况,再把an放到k个盒子里的一个:k*s(n-1,k)

考虑边界情况:

(1)若k==0,return 0

(2)若n<k,return 0(无法满足没有空盒子)

(3)若n==k,return 1

(4)若k==1,return 1

代码如下:

#include<iostream>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int INF=0x3f3f3f3f,mod=12345;
const int N=10005,N1=105;

ll dfs(int n,int k){
    if(n<k||k==0)return 0;
    if(n==k||k==1)return 1;
    return dfs(n-1,k-1)+k*dfs(n-1,k);
}

int main(){
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF){
        printf("%lld\n",dfs(n,k));
    }
}

 思路:

这个题刚开始看的时候并没看出来哪递归了QwQ,好菜

* + 11.0 12.0 + 24.0 35.0

也就是 (11.0+12.0) * (24.0+35.0)

可以看出,每到一个符号,他就执行运算,一层一层向下递归

atof()用法:

atof的运用范围非常少,但是有一些特定的题目需要它,它可以将字串转换成浮点型数,非常的方便,它需要运用#include<algorithm>头文件。atof()会扫描参数字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时才结束转换,并将结果返回。参数字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2。
代码如下:

#include<iostream>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<sstream>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int INF=0x3f3f3f3f,mod=12345;
const int N=1005,N1=105;
char a[100],b[100];

int main(){
    scanf("%s%s",a,b);
    double a1=atof(a),b1=atof(b);
    printf("%f %f\n",a1,b1);
}

#include<iostream>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<sstream>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int INF=0x3f3f3f3f,mod=12345;
const int N=1005,N1=105;
char a[100];
double solve(){
    scanf("%s",a);
    int len=strlen(a);
    if(a[0]=='+'||a[0]=='-'||a[0]=='*'||a[0]=='/'){
        if(a[0]=='+')return solve()+solve();
        if(a[0]=='-')return solve()-solve();
        if(a[0]=='*')return solve()*solve();
        if(a[0]=='/')return solve()/solve();
    }
    else {
        return atof(a);
    }
}

int main(){
    printf("%f\n",solve());
}

思路:

刚开始看题的时候一脸懵逼qwq,想着是分别把每个因数递归处理,比如12

2*6或3*4

再分别处理6和4

于是乎:2*6可以得到2*2*3,3*4可以得到3*2*2

重复啦!!!怎么才能不重复的求出分解的种数呢?

根据题上的:1<a1≤a2≤a3≤...≤an

我们可以控制递归条件,使得因数呈递增状态

比如24:一共7种

具体见代码:

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int INF=0x3f3f3f3f;
const int N=10000005,mod=32767;
int cnt;
void solve(int b,int n){
    if(n==1)return ;
    for(int i=b;i*i<=n;i++){
        if(n%i==0&&i<=n/i){//数n看成i*(n/i),所以cnt++
            cnt++;
            solve(i,n/i);//n/i的因数不能小于i
        }
        if(i>n/i)break;//分解出的因数要递增
    }
}

int main(){
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        cnt=1;//代表n本身
        solve(2,n);
        printf("%d\n",cnt);
    }
}

思路:


int solve(int app,int pla){
    if(app==0||pla==1)return 1;//如果苹果为0,或盘子为1返回1种方案
    if(app<pla)return solve(app,app);
    //若是苹果数小于盘子数,则至少有pla-app个空盘子,该情况等于solve(app,app)
    if(app>=pla)return solve(app,pla-1)+solve(app-pla,pla);
    //若苹果数大于等于盘子数,则分两种情况:
    //1.至少有一个空盘子solve(app,pla-1)
    //2.没有空盘子,也就是说每个盘子都有苹果,这种情况相当于从每个盘子中拿出一个苹果solve(app,pla-app)
}

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int INF=0x3f3f3f3f;
const int N=10000005,mod=32767;

int solve(int app,int pla){
    if(app==0||pla==1)return 1;
    if(app<pla)return solve(app,app);
    if(app>=pla)return solve(app,pla-1)+solve(app-pla,pla);
}

int main(){
    int n,m,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&m,&n);
        printf("%d\n",solve(m,n));
    }
}

思路:

看似挺简单,却写了好久qwq,注意递归结束条件

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int INF=0x3f3f3f3f;
const int N=10000005,mod=32767;
int mi[25];
void solve(int n){
    if(n==0||n==2){
        printf("%d",n);
        return ;
    }
    for(int i=15;i>=0;i--){
        if(mi[i]==n){//数n正好是2的整数次幂时,不用+
            printf("2");
            printf("(");
            solve(i);
            printf(")");
            break;
        }
        if(mi[i]<n){//数n不是2的整数次幂时,把n分解成两个数来求解
            solve(mi[i]);
            printf("+");
            solve(n-mi[i]);
            break;
        }
    }
}

int main(){
    int n;
    mi[0]=1;
    for(int i=1;i<=15;i++){
        mi[i]=mi[i-1]*2;
    }
    scanf("%d",&n);
    solve(n);
    printf("\n");
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值