1225. Flags

Time limit: 1.0 second
Memory limit: 64 MB
On the Day of the Flag of Russia a shop-owner decided to decorate the show-window of his shop with textile stripes of white, blue and red colors. He wants to satisfy the following conditions:
  1. Stripes of the same color cannot be placed next to each other.
  2. A blue stripe must always be placed between a white and a red or between a red and a white one.
Determine the number of the ways to fulfill his wish.
Example. For N = 3 result is following:

Input

N, the number of the stripes, 1 ≤ N ≤ 45.

Output

M, the number of the ways to decorate the shop-window.

Sample

input output
3
4
Problem Source: 2002-2003 ACM Central Region of Russia Quarterfinal Programming Contest, Rybinsk, October 2002
 
 
        最近被问到了这个问题,其实是一个很简单的DP,但就有人纠结为什么就变成了斐波那契。
        首先说下DP的思路:有三种状态,白、蓝、红,直接对应到0、1、2吧,于是可以定义一个数组dp[46][3],因为蓝的只能在白和红之间,所以只有一格的时候初始状态为:dp[1][0]=dp[1][2]=1,dp[1][1]=0。
        对于接下来的每格,这一格是红色依赖于前一格不是红色,这一格是白色依赖于前一格不是白色;另外假设如果前一格是蓝色,那么这一格是红/白色就依赖于前面第二格不是红/白色,于是有下面的递推:
                白色:dp[i][0]=dp[i-1][2]+dp[i-2][2];
                蓝色:dp[i][1]=dp[i-1][0]+dp[i-1][2];
                红色:dp[i][2]=dp[i-1][0]+dp[i-2][0];
        最后把dp[N][0]和dp[N][2]加起来就是所有情况的总和了,因为最后一格无论如何也不可能是蓝色的。
 
 int main2() {
int N;long long dp[][]={};
dp[][]=dp[][]=;
scanf("%d", &N);
for(int i=; i<=N; i++)
dp[i][]=dp[i-][]+dp[i-][],
dp[i][]=dp[i-][]+dp[i-][],
dp[i][]=dp[i-][]+dp[i-][];
printf("%lld\n",dp[N][]+dp[N][]);
return ;
}
        然后我们可以发现一些有趣的事情,其实白色和红色的递推是相互依赖的,而蓝色根本不会有什么用,因为这一格是蓝色取决于前一格不是蓝色,即前一格是白色或红色的情况总和,这个数量并不能为下一格提供对前两格的有效判断。
        仔细观察发现,原来白色和红色就是两个相同的斐波那契数列,这样就好办了,两个合成一个,f[1]=f[2]=2,f[i]=f[i-1]+f[i-2],最后f[N]就是N格的情况总和。
 
 int main() {
int N;long long dp[]={,,};
scanf("%d", &N);
for(int i=; i<=N; i++)
dp[i]=dp[i-]+dp[i-];
printf("%lld\n",dp[N]);
return ;
}
        最后,一眼看出是斐波那契是如何做到的呢?首先无视蓝色,第一个格子f[1]=2,只有白/红两种情况,因为白/红不能连续出现,所以这一格是什么,已经定死了下一格是什么,于是第i个格子f[i]=f[i-1]。然后看看加入蓝色会发生什么:如果前一格是蓝色,那么当前格子一定是和前两格不同的颜色,则f[i]=f[i-2];综合考虑下,f[i]=f[i-1]+f[i-2]。
 
 
 
 
 
 

Ural 1225. Flags 斐波那契DP的更多相关文章

  1. 【斐波那契DP】HDU 4639——HeHe

    题目:点击打开链接 多校练习赛4的简单题,但是比赛的时候想到了推导公式f(n)=f(n-1)+f(n-2)(就是斐波那契数列),最后却没做出来. 首先手写一下he(不是hehe)连续时的规律.0-1 ...

  2. 一只小蜜蜂(斐波那契dp)

    有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行.请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数. 其中,蜂房的结构如下所示. Input输入数据的第一行是一个整数N,表示测试实例的个数,然后是 ...

  3. 递推DP URAL 1225 Flags

    题目传送门 /* 1 r; 2 b; 3 w 2不能在最前面,所以dp[1] = 2; dp[2] = 2: 13 or 31 dp[i] = dp[i-1] + dp[i-2]; 只加1或3时,总数 ...

  4. CodeAction_beta02 斐波那契 (多维DP)

    题面: solution: 这题和斐波那契数列没有任何关系!!!!! 这题就是一个无脑DP!!!!!!!!!! 因为所有数都要出现至少一次,所以只需考虑其组合而不用考虑其排列,最后乘个 n!就是了(意 ...

  5. [ZJOI2011]细胞——斐波那契数列+矩阵加速+dp

    Description bzoj2323 Solution 题目看起来非常复杂. 本质不同的细胞这个条件显然太啰嗦, 是否有些可以挖掘的性质? 1.发现,只要第一次分裂不同,那么互相之间一定是不同的( ...

  6. DP思想在斐波那契数列递归求解中的应用

    斐波那契数列:1, 1, 2, 3, 5, 8, 13,...,即 f(n) = f(n-1) + f(n-2). 求第n个数的值. 方法一:迭代 public static int iterativ ...

  7. Xorequ(BZOJ3329+数位DP+斐波那契数列)

    题目链接 传送门 思路 由\(a\bigoplus b=c\rightarrow a=c\bigoplus b\)得原式可化为\(x\bigoplus 2x=3x\). 又异或是不进位加法,且\(2x ...

  8. 斐波那契数列 矩阵乘法优化DP

    斐波那契数列 矩阵乘法优化DP 求\(f(n) \%1000000007​\),\(n\le 10^{18}​\) 矩阵乘法:\(i\times k\)的矩阵\(A\)乘\(k\times j\)的矩 ...

  9. HDU 2041 超级楼梯 (斐波那契数列 & 简单DP)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2041 题目分析:题目是真的水,不难发现规律涉及斐波那契数列,就直接上代码吧. 代码如下: #inclu ...

随机推荐

  1. Android 开发环境在 Windows7 下的部署安装

    Android SDK Android SDK 为 Android 应用的开发.测试和调试提了必要的API库和开发工具. ADT Bundle 下载 如果你是一个android 开发新手,推荐你下载使 ...

  2. ASP.NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序

    原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...

  3. PostgreSQL介绍以及如何开发框架中使用PostgreSQL数据库

    最近准备下PostgreSQL数据库开发的相关知识,本文把总结的PPT内容通过博客记录分享,本随笔的主要内容是介绍PostgreSQL数据库的基础信息,以及如何在我们的开发框架中使用PostgreSQ ...

  4. Windows进程间通信—命名管道

    命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节.我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信.与Socket网络通信相比,命名管道不再需要编写身份验证的代码.将 ...

  5. C#开发微信门户及应用(38)--微信摇一摇红包功能

    摇一摇周边红包接口是为线下商户提供的发红包功能.用户可以在商家门店等线下场所通过摇一摇周边领取商家发放的红包.我曾经在<C#开发微信门户及应用(28)--微信“摇一摇·周边”功能的使用和接口的实 ...

  6. 三个linux系统共存,修改默认启动

     一个mint,一个ubuntu,想要默认启动ubuntu,那么咱们这么来:修改启动顺序,我们需要修改Ubuntu的GRUB配置文件.使用常见的编辑程序如"gedit"就可以很方便 ...

  7. SpringMVC启动过程详解(li)

    通过对SpringMVC启动过程的深入研究,期望掌握Java Web容器启动过程:掌握SpringMVC启动过程:了解SpringMVC的配置文件如何配置,为什么要这样配置:掌握SpringMVC是如 ...

  8. linux安装中文字体

    一.查看系统字体 在开始安装之前,我们先查看系统中已经安装的字体. 要查看系统中已经安装的字体,我们可以使用fc-list命令进行查看.如果系统中没有该命令的话,我们需要先安装相关的软件包. 在cen ...

  9. C#中日期和时间相加的方法

    可能对于初入此行业人来说有些困惑,实现起来有一丝复杂. 比如说时间是:2016-08-05 14:46:30,中间过了56秒钟.要求得出56秒之后的时间格式是:年月日时分秒 下面介绍最简单的办法, m ...

  10. 深入理解js的变量提升和函数提升

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...