BNUOJ 4064 条形码设计 (动态规划 + 递推)

条形码设计

1000ms                                                     65536KB
64-bit integer IO format:  %lld      Java class name:  Main

校ACM队准备筹划向学校批请一个专用机房。但是为了防止它变成公用机房,FL建议采用刷卡进入的办法,她设计了一种条形码,每人都对应一个。这种大小为2*n的条形码由以下三种元素构成:1*2、2*1、2*2的长方形方格。但是我们同样也知道,很多人都容易在刷卡时把卡的位置搞反。为了避免机器错误的处理,我们认为下图的两种条形码是一样的(图中颜色只是为方便说明,不用考虑)。

FL现在很想知道一个问题,就是用她的这种条形码编码方式,对于一个给定的长度n最多能有多少不同的条形码可供使用?  

Input

多组测试数据,每一行一个正整数n(n≤28),以n = 0时作为结束。 

Output

最与每一组数据,先输出“Case k:”,其中k代表case数,接下来输出一个数,可用的的条形码数目m(m不超过231.)

Sample Input

1
2
3
4
5
0

Sample Output

Case 1:1
Case 2:3
Case 3:3
Case 4:8
Case 5:12

Hint

注意输出英文字母的大小写也必须正确。

这是前天比赛的一道题,今天终于弄明白了。

         如果不考虑题中的限制条件,只考虑有多少种排列方式,则F(n) = F(n-1) + 2 * F(n-2),这里面既包括对称的,又包括不对称的,但是对称的只算了一次。考虑到题中的限制条件,不对称的被算了2次,假设最后的输出结果为ans,则ans * 2 = (对称的方式 + 不对称的方式)* 2。所以只需求出对称的排列方式,然后加上F(n),结果就是ans的2倍,除以2就是最终结果。

那么如何求对称的排列方式有多少种呢?
如果n为奇数,如果对称,则中间一定放一个1*2的,只有这样才能保证对称,则对称方式共有b[n] = F[(n-1)/2];
如果n为偶数,如果中间放两个1*2的竖条,如下图,
则一共有b[n] = F[n/2]种对称方式。     如果中间放2个2*1的或者1个2*2的,如下图,则一共有b[n] = F[(n-2)/2] * 2种对称方式。

所以当n为偶数时,总的对称方式有b[n] = F[n/2] + F((n-2)/2] * 2种。


参考代码:
#include<cstdio>
int main()
{
    int i, n, cas = 0;
    int a[30] = {0, 1, 3}, b[30] = {0, 1, 3};
    for(i = 3; i <= 28; i++)
    {
        a[i] = a[i-1] + 2 * a[i-2];
        if(i & 1)
            b[i] = a[(i-1)/2];
        else
            b[i] = a[i/2] + 2 * a[(i-2)/2];
    }
    while(~scanf("%d",&n) && n)
    {
        printf("Case %d:%d\n",++cas, (a[n]+b[n])/2);
    }
    return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值