hdu 1297 递推难题

这题的话,我能玩一年

今天做了很多递推的题,这题无疑是最复杂的


其实可以看出来,2,3,4,5为一类,不妨定义为2型,1,6为一类,定义为1型

规定num[i]为结尾是i的凹槽的数量

我们可以能轻易的推出 sum = num[1]*2+num[2]*4

现在我们开始分析这个递推式的构成

根据第n个凹槽前 能不能构成一把lock,我们将情况分为两类

A:能构成lock

1.如果当前结尾为1类,我们用‘1’分析好了(下面也是用1),n-1的结尾必然不能是‘6’,因为1和6不能直接相连,根据题意就知道了,可以推出num1[i] = lock[i-1] - num1[i-1]

2.如果当前结尾为2类,那和n-1的结尾无任何关系,则num2[i] = lock[i-1]

B:加入n后才能构成lock

很容易推出前n-1应该有两种种类,因为题目说了至少有三种种类的凹槽

1.如果当前结尾是‘1’(1类),我们要分两种讨论,有‘6’和无'6',至于原因,还是因为‘6’不能放在n-1结尾处

a.取‘6’

(哎,数学符号打不出来额,文字描述好了)

从剩下的4个内取1个,组合数为4,排列数为(2^(n-2)-1)  因为n-1处不能放‘6’

b.不取‘6’

从剩下的4个内取两个,组合数为为6,排列数为(2^(n-1)-2)

2.如果当前是‘2’(2类)

从剩下的5个内取两个,但是1和6不能同时取,所以-1,则组合数为9,排列数为(2^(n-1)-2)


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;



int main()
{
    __int64 lock[26],num1[26],num2[26];
    __int64 t;
    num1[3] = 16;
    num2[3] = 18;
    lock[3] = 104;
    t = num1[3];

    for(int i=4;i<26;i++){
        num1[i] = lock[i-1] - t; //sub num6[i-1]
        num2[i] = lock[i-1];

        num1[i] += 4*((int)pow((float)2,i-2)-1)+6*((int)pow((float)2,i-1)-2);
        num2[i] += 9*((int)pow((float)2,i-1)-2);

        lock[i] = 2*num1[i] + 4*num2[i];
        t = num1[i];
    }

    for(int i=3;i<26;i++){
        printf("N=%d: %I64d
",i,lock[i]);
    }
    //cout << "Hello world!" << endl;
    return 0;
}
View Code
在一个谎言的国度,沉默就是英雄
原文地址:https://www.cnblogs.com/EdsonLin/p/5342924.html