• <每日一题> Day6:HDU递推专题完结


    原题链接

    这是我自己Clone的专题,A,B题解昨天发过了

    C:参考代码:

    /*
        很容易我们可以手推出n = 1, 2, 3时的情况,我们假设前n - 1
        列已经放好,方法有dp[n - 1]种,第n列很显然有1种方法,那我
        再假设前n - 2列已经放好,方法有dp[n - 2]种,此时我们知道
        第n - 1和第n列肯定是横着放的,如果他们竖着放就和前n - 1列
        放好的情况相同,所以我们可以推出方程dp[n] = dp[n - 1] + dp[n - 2]; 
    */
    #include <cstdio>
    using namespace std;
    
    typedef long long int ll;
    const int maxn = 50 + 5;
    int n;
    ll dp[maxn];
    
    int main() {
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        for(int i = 4; i <= maxn; i ++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        while(~scanf("%d", &n)) {
            printf("%lld
    ", dp[n]);
        }
        return 0;
    }

    D:参考代码:

    /*
        解题思路:还是一如既往的递推...这个题和涂格子的那个题目很像
        很容易我们可以手推出n = 1, 2, 3的情况,对于第n个格子,我
        们假设前n - 1个格子已经涂好了,那么我们知道如果第n - 1个格子
        是O,那么我们第n个格子有两种涂法,如果不是O,我们第n个格子有
        三种涂法,对于第n - 1个格子,我们可以看第n - 2个格子,如果
        第n - 2个格子
    */
    #include <cstdio>
    using namespace std;
    
    typedef long long int ll;
    const int maxn = 40 + 5;
    int n;
    ll dp[maxn];
    
    int main() {
        dp[1] = 3;
        dp[2] = 8;
        dp[3] = 22;
        for(int i = 4; i <= maxn; i ++) {
            dp[i] = 2 * (dp[i - 1] + dp[i - 2]);
        }
        while(~scanf("%d", &n)) {
            printf("%lld
    ", dp[n]);
        }
        return 0;
    }

    E:参考代码:

    /*
        同样是递推,手推出n = 2, 3时所有未中奖的情况,我们先把
        他们抽奖假设为放东西,那么第n个参与者放东西时它可以放到
        任意一个前面的位置即n - 1种方法,我们假设为k为n放置的坐
        标,那么我们还需要将第k个放到其它位置,我们知道当第k个放
        到第n个位置时,其它n - 2个有dp[n - 2]种方法,当第k个不放
        到第n个位置时,这n - 1个有dp[n - 1]种方法放置,所以我们
        可以得出dp[n] = (n - 1) * (dp[n - 1] + dp[n - 2])。
    */
    #include <cstdio>
    using namespace std;
    
    typedef long long int ll;
    const int maxn = 20 + 5;
    int c, n;
    ll dp[maxn];
    ll mather[maxn];
    
    int main() {
        dp[2] = 1;
        dp[3] = 2;
        mather[2] = 2;
        mather[3] = 6;
        for(int i = 4; i <= maxn; i ++) {
            dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]);
            mather[i] = mather[i - 1] * i;
        }
        scanf("%d", &c);
        while(c --) {
            scanf("%d", &n);
            printf("%.2f%%
    ", ((double)dp[n] * 100) / mather[n]);
        }
        return 0;
    }

    F:参考代码:

    /*
        这个题可能是上一题的加强版?
        上一题是说n个人全为选中正确的百分比,这题是求n个里有m个全
        未选中的种数,高中同学应该都能想到选出m个让他们全不合格就行,
        C(n, m) * dp[m]即为方程了。
    */
    #include <cstdio>
    using namespace std;
    
    typedef long long int ll;
    const int maxn = 20 + 5;
    int c, n, m;
    ll dp[maxn], mather[maxn];
    
    int main() {
        dp[2] = 1;
        dp[3] = 2;
        for(int i = 4; i <= maxn; i ++)
            dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]);
        scanf("%d", &c);
        while(c --) {
            scanf("%d %d", &n, &m);
            ll p = 1;
            for(int i = n - m + 1; i <= n; i ++)
                p *= i;
            for(int i = 1; i <= m; i ++)
                p /= i;
            printf("%lld
    ", p * dp[m]);
        }
        return 0;
    }

    G:参考代码:

    /*
        这题一开始没有思路emm,去网上查了一下发现受益匪浅。
        参考直线相交,我们发现每增加一条直线就会增加n - 1个交点,
        就会增加n个平面,所以我们知道对于直线相交产生的平面个数有
        dp[n] = dp[n - 1] + n;
    
        对于折线呢,我们发现,每画一条折线我们总是能和之前的n - 1
        条折线多出4个交点,即总共多出4 * (n - 1) 个交点,那么就多出了
        4 * (n - 1) + 1个面,就可以得出递推方程dp[n] = dp[n - 1] + 4 * [n - 1] + 1
    
        对于Z型折线,画一画就可以知道每增加一条z型折线,最多能与原图的n - 1条z型折线
        共多生成9 * (n - 1) 个交点,也即可以得到递推方程为
        dp[n] = dp[n - 1] + 9 * (n - 1) + 1;
    */
    #include <cstdio>
    using namespace std;
    
    typedef long long int ll;
    const int maxn = 10000 + 5;
    int c, n;
    ll dp[maxn];
    
    int main() {
        dp[1] = 2;
        for(int i = 2; i <= maxn; i ++) {
            dp[i] = dp[i - 1] + 4 * (i - 1) + 1;
        }
        scanf("%d" ,&c);
        while(c --) {
            scanf("%d", &n);
            printf("%lld
    ", dp[n]);
        }
        return 0;
    }
  • 相关阅读:
    OSGI简介
    公司僵尸帐号引发了一系列的入侵事件-细说密码强度验证的重要性
    为其他对象提供一种代理以控制对这个对象的访问-代理模式
    运用共享技术有效地支持大量细粒度的对象-享元模式
    移动APP为什么要开发两套Android和IOS-桥接模式
    非法疫苗引发的思考 -外观模式
    你们还记得张江男、张江女两张图片吗?-装饰模式
    一个程序员的蜕变(我是如何成为架构师的)
    公司新加了一台友宝自动售货机引发的思考-适配器模式
    程序员如何应对北上广高房价示例解说-建造者模式
  • 原文地址:https://www.cnblogs.com/bianjunting/p/10928392.html
Copyright © 2020-2023  润新知