百度之星 12-12 题目二

本文深入探讨了如何通过巧妙地运用斐波那契数列的性质来解决一个涉及不同层间避免两个1相邻排列的数学问题。文章详细介绍了问题背景、转化策略、解题思路及关键步骤,提供了清晰的代码实现和解析,帮助读者理解复杂问题的简化路径。

阅读http://blog.youkuaiyun.com/niuxianzhuo/article/details/8285854后,深有感触。

代码如下:

#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;

const int MOD = 2012;

/*
    给定一个边长为偶数个(N)方格组成的正方形
    现在由内到外每一个四边形为一层,每个方格
    由0,1组成,现在要求是不同层之间不能够有
    两个1相邻,现在给定N,问多少种情况
    这里有一个很巧妙的转化,即是将我们关心的
    相同层的关系转化为不同层的关系,这个转化
    就使的问题变得独立和模块化,详见大牛博客 
    http://blog.youkuaiyun.com/niuxianzhuo/article/details/8285854
*/

int f[505], ret[505], N;

/* f用来保存斐波那契数,一波斐波那契数的含义就是
   f[i]表示一个长度为i的格子放置不相邻的1,有多少种放置方式 
   那么对于f[i] i >= 3 就有类似hdu2046的性质,即对于i+1个方格
   我们直接放置0是可以的,因此f[i] = f[i-1] + x, x为其余部分
   那么如果要放置1的话,那么要求i个位置必须放置0,那么方案数
   就是f[i-2]既然i+1号位置1,0两种情况都已经考虑,因此f[i] = f[i-1] +f[i-2]
   就是最后的结果,其满足斐波那契数列的性质,有f[1] = 2, f[2] = 3 
*/ 
// 输入数据N的范围为2-500之间的偶数

void solve() {
    f[1] = 2, f[2] = 3;
    for (int i = 3; i <= 500; ++i) {
        f[i] = f[i-1] + f[i-2];
        f[i] %= MOD;
    } // 求出前500个递推数
    for (int i = 2; i <= 500; i+=2) {
        ret[i] = 1;
        // 最长的L长度为i-1 
        for (int j = i-1; j >= 1; j -= 2) {
            ret[i] *= f[j];
            ret[i] %= MOD;
        }
        ret[i] *= ret[i];
        ret[i] %= MOD;
        ret[i] *= ret[i];
        ret[i] %= MOD;
    } // 求解最后的答案
}

int main() {
    solve(); // 先进行一次预处理
    while (scanf("%d", &N) == 1) {
        printf("%d\n", ret[N]);
    }
    return 0;    
}

 

转载于:https://www.cnblogs.com/Lyush/archive/2012/12/13/2816423.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值