XJOI 3266 Dyeing 染色 题解

英文

Time Limit:1s Memory Limit:256M

Description

N grid in a line.Using three colour(red,pink and green) to dye the grid,each grid dyeing one colour,the rule is every two adjacent grid should be different colour,and the first grid and the last grid in the line should be different colour.Please calculate the ways you dye.

Input

One integer n 1<=n<=50

Output

One integer.

Sample Input

2

Sample Output

6

中文

时间:1s 空间:256M

题目描述:

有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.

输入格式:

输入一个整数n

输出格式:

输出一个整数

样例输入:

2

样例输出:

6

约定:

0<=n<=50

扫描二维码关注公众号,回复: 2360372 查看本文章

提示:

看到这题后,是不是准备先来个暴力?没错,暴力已经准备好了:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ; 
int a [ 101 ] , n ;
long long ans = 0 ;
void dfs ( int k ) 
{
    if ( k > n )
    {
        ans ++ ;
    //  for ( int i = 1 ; i <= n ; i ++ ) printf ( "%d" , a [ i ] ) ;
    //  printf ( "      %lld" , ans ) ;
    //  printf ( "\n" ) ;
    //以上代码可以输出方案
        return ;
    } else
    {
        if( k != n)
        {
            for ( int i = 1 ; i <= 3 ; i ++ ) if ( i != a [ k - 1 ] )
            {
                a [ k ] = i ;
                dfs ( k + 1 ) ;
                a [ k ] = 0 ;           
            }
        } else
        {
            for ( int i = 1 ; i <= 3 ; i++ ) if ( i != a [ k - 1 ] && i != a [ 1 ] )
            {
                a [ k ] = i ;
                dfs ( k + 1 ) ;
                a [ k ] = 0 ;
            }
        }
    }
    return ;
}
int main ( )
{
    scanf ( "%d" , & n ) ;
    memset ( a , 0 , sizeof ( a ) ) ;
    if ( n != 0 ) dfs ( 1 ) ;//典型的DSF,特判0是必要的。
    printf ( "%d" , ans ) ;
    return 0 ;
}

然而,这怎么可能是正解呢?n的最大值可是50啊。以上的算法,n只能坚持到24、25左右,是万万不行的。所以,我们就可以想到用数学方法解释了。假设n个方格的方案数为f(n),我们可以先考虑第n-1个方格。
第一种情况:如果n-1个方格与第一个方格不同,那么第n个方格(也就是最后一个方格),只有唯一一种情况,那么就增加f(n-1) 种方案了。为什么是f(n-1)呢?因为当n-1个格子时,题目规定了首尾不同色,升级到n个以后,就在最后加上一个与第n-1个和第n个都不相同的颜色就可以了。
第二种情况:如果n-1个方格的颜色与第1个方格颜色相同,那么第n个方格就应当有两种情况了。而在此时,第n-2个方格必定与n-1个方格不同色,因此也与第1个方格不同色,所以在第n个方格的这种情况中,前n-2个方格的情况数是f(n-2),后面2个方格的情况是两种,所以就增加了2*f(n-2)种方案了。
综上所述,f(n)=f(n-1)+2*f(n-2) (n>3) 就解释清楚了。注意初始条件就行了,还要开long long ,详见代码(正解):

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 300
using namespace std ;
long long f [ N ] , n ; 
int main ( )
{
    cin >> n ;
    f [ 0 ] = 0 ;
    f [ 1 ] = 3 ;
    f [ 2 ] = 6 ;
    f [ 3 ] = 6 ;
    for ( int i = 4 ; i <= n ; i ++ ) f [ i ] = 2 * f [ i - 2 ] + f [ i - 1 ] ;
    cout << f [ n ] ;
    return 0 ;
}

就是这么短。

相关链接:

XJOI 题解小全:
https://blog.csdn.net/zj_mrz/article/details/80949787

XJOI 3265 Climb the stairs 爬楼梯 题解:
https://blog.csdn.net/zj_mrz/article/details/80970052

XJOI 3410 看图找规律 题解:
https://blog.csdn.net/zj_mrz/article/details/81044076

猜你喜欢

转载自blog.csdn.net/zj_mrz/article/details/81060961
今日推荐