HDOJ(HDU).2044-2049 递推专题

来源:互联网 发布:数据库的逻辑结构设计 编辑:程序博客网 时间:2024/05/19 07:08

HDOJ(HDU).2044-2049 递推专题

点我挑战题目

HDU.2044

题意分析

先考虑递推关系:从1到第n个格子的时候由多少种走法?

这里写图片描述

这里写图片描述
如图,当n为下方格子的时候,由于只能向右走,所以有2中走法。当n为上方格子的时候,由于只能向右走,所以也有2种走法。
不妨用a[n]来表示第n个格子有几种走法,根据上述描述,不难找出递推关系,a[n] = a[n-1] + a[n-2]。但是对于n<2的数字,就不适用了。也很简单,n<2的时候数一下即可,从1走到1,只有一种走法,从1走到2,有一种走法。问题就解决了。
然后我们接着考虑从b走到c有几种走法。不放就看样例给的3-6。从图中可以看出,从3-6走的方法和从1-4走的方法总数是一样的。故从b到c的的方法数为a[c-b+1].

代码总览

/*    Title:HDOJ.2044    Author:pengwill    Date:2017-2-13*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define ll long longusing namespace std;ll a[51];int main(){    a[1] = a[2] = 1;    for(int i = 3 ; i<=50 ;++i) a[i] = a[i-1] + a[i-2];    int b,c,t;    scanf("%d",&t);    while(t--){        scanf("%d%d",&b,&c);        printf("%lld\n",a[c-b+1]);    }    return 0;}

HDU.2045

题意分析

由于前一个颜色的选择会影响到下一个颜色的选择,对于前n个格子的涂法,就要对前n-1个格子的颜色进行分析。由于要求是首位的颜色不同,那么就要对第n-1个格子是否与第一个格子颜色相同分类讨论。a[n]代表前n个格子的涂法。
若第一个格子与第n-1个格子的颜色不同,那么第n个格子的就有1种涂法;若第n-1个格子与第一个格子颜色相同,那么第n个格子就有2种涂法,需要注意的是,其实这种情况的方案数是与a[n-2]有关的,因为此时方案数是a[n-2] * 1 * 2 (n-1格子颜色已经确定了)

代码总览

/*    Title:HDOJ.2045    Author:pengwill    Date:2017-2-13*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define ll long longusing namespace std;ll a[51];int main(){    a[1] = 3; a[2] = 6; a[3] = 6;    for(int i = 4; i<=50; ++i) a[i] = a[i-2]*2 + a[i-1];    int n;    while(scanf("%d",&n) != EOF){        printf("%lld\n",a[n]);    }    return 0;}

HDU.2046

题意分析

详情请见此

代码总览

/*    Title:HDOJ.2046    Author:pengwill    Date:2017-2-13*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define ll long longusing namespace std;ll a[51];int main(){    a[1] = 1; a[2] = 2;    for(int i = 3; i<=50; ++i) a[i] = a[i-2] + a[i-1];    int n;    while(scanf("%d",&n) != EOF){        printf("%lld\n",a[n]);    }    return 0;}

HDU.2047

题意分析

由于n-1位是否为O,影响第n位的选择,所以很明显,这道题有2种状态,一种是n-1是O,一种是n-1不是O。第n位的方案数就是,n为O的方案 + n不为O的方案。
a[n]表示O结尾的方案数 b[n]不是以O结尾的方案数,c[n]表示总的方案数。那么c[n] = a[n] + b[n]。
不难发现:
a[1] = 1; a[2] = 2; c[1] = 3;
b[1] = 2; b[2] = 6; c[2] = 8;
然后分别找一下a[n]和b[n]的递推关系式:
由于不能有O相连,那么n-1不为O的时候,n位才有可能为O,可以得出:a[n] = b[n-1]
接着考虑什么时候第n位为非O呢,当第n-1位是O的时候,n可能有EF2种非O选择,当n-1位为O的时候,也有EF2种非O选择,于是有:b[n] = 2 * (a[n-1] + b[n-1])
有了ab的递推关系式,根据c[n] = a[n] + b[n] 问题也就迎刃而解了。

代码总览

/*    Title:HDOJ.2047    Author:pengwill    Date:2017-2-13*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define ll long longusing namespace std;ll a[41],b[41],c[41];int main(){   // a以O结尾的结果数量 b非以O的数量    a[1] = 1; a[2] = 2; c[1] = 3;    b[1] = 2; b[2] = 6; c[2] = 8;    for(int i = 3; i<=40; ++i){        a[i] = b[i-1];        b[i] = 2*(a[i-1] + b[i-1]);        c[i] = a[i] + b[i];    }    int n;    while(scanf("%d",&n) != EOF){        printf("%lld\n",c[n]);    }    return 0;}

HDU.2048

题意分析

此题的递推关系体现在错排公式,详情百度。

代码总览

/*    Title:HDOJ.2048    Author:pengwill    Date:2017-2-13*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define ll long longusing namespace std;ll a[21]={0,0,1},b[21] = {0,1};ll cal(int i){    if(b[i] != 0) return b[i];    else return (cal(i-1)*i);}void init(){    for(int i = 1;i<=20;++i)        b[i] = cal(i);    for(int i = 3; i<=20;++i)        a[i] = (i-1) * (a[i-1]+a[i-2]);}int main(){    init();    int t;    scanf("%d",&t);    while(t--){        int n;        scanf("%d",&n);        printf("%.2f%%\n",100.0*a[n]/b[n]);    }}

HDU.2049

题意分析

此题的递推关系体现在错排公式,详情百度。

代码总览

/*    Title:HDOJ.2049    Author:pengwill    Date:2017-2-13*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define ll long longusing namespace std;ll a[21]={0,0,1},b[21] = {1,1};//a是错排,b是全排列ll cal(int i){    if(b[i] != 0) return b[i];    else return (cal(i-1)*i);}void init(){    for(int i = 1;i<=20;++i)        b[i] = cal(i);    for(int i = 3; i<=20;++i)        a[i] = (i-1) * (a[i-1]+a[i-2]);}int main(){    init();    int t;    scanf("%d",&t);    while(t--){        int n,m;        scanf("%d%d",&n,&m);        printf("%lld\n",b[n]/b[m]/b[n-m] * a[m]);    }}
0 0
原创粉丝点击