首页 » 技术分享 » 【备战蓝桥杯】【动态规划】【 瓷砖铺放2】

【备战蓝桥杯】【动态规划】【 瓷砖铺放2】

 

问题描述

有一长度为 N(1<=N<=10)的地板,给定三种不同瓷砖:一种长度为 1,一种长度为 2,另一种长度为 3,数目不限。要将这个长度为 N 的地板铺满,
并且要求长度为 1 的瓷砖 不能相邻,一共有多少种不同的铺法?

例如,长度为 4 的地板一共有如下 4 种铺法:

4=1+2+1

4=1+3

4=2+2

4=3+1

编程求解上述问题。

第一种

输入格式

只有一个数 N,代表地板的长度。

输出格式

方案总数。

样例输入

4

样例输出

4

动态规划

n表示长度

最后一块不是1   (则是2或3) 最后一块是1
总共               
f_not1(1)=0 
f_1(1)=1
f(1)
f_not1(2)=1   
 f_1(2)=0
f(2)
f_not1(3)=2 
 f_1(3)=1
f(3)

f_not1(4)=f(1)+f(2)

铺满1块地板的数量(再铺一块3)+

铺满2块地板的数量(再铺一块2)

 f_1(4)=f_not1(3)

最后一块不是1的f_not1(3)

f(4)

f_not1(5)=f(2)+f(3)

铺满2块地板的数量(再铺一块3)+

铺满3块地板的数量(再铺一块2)

f_1(5)=f_not1(4)

最后一块不是1的f_not1(4)


f(5)

f_not1(6)=f(3)+f(4)

铺满3块地板的数量(再铺一块3)+

铺满4块地板的数量(再铺一块2)

f_1(6)=f_not1(5)                                 f(6)
…… …… ……

f_not1(n)=f(n-3)+f(n-2)

铺满n-3块地板的数量(再铺一块3)+

铺满n-2块地板的数量(再铺一块2)

f_1(n)=f_not1(n-1) f(n)

或者(只是看的方式不一样)

第一块不是1   (则是2或3) 第一块是1
总共               
f_not1(1)=0 
f_1(1)=1
f(1)
f_not1(2)=1   
 f_1(2)=0
f(2)
f_not1(3)=2 
 f_1(3)=1
f(3)

f_not1(4)=f(1)+f(2)

铺满最后1块地板的数量(第一块再铺一块3)+

铺满最后2块地板的数量(第一块再铺一块2)

 f_1(4)=f_not1(3)

第一块不是1的f_not1(3)

f(4)

f_not1(5)=f(2)+f(3)

铺满最后2块地板的数量(第一块再铺一块3)+

铺满最后3块地板的数量(第一块再铺一块2)

f_1(5)=f_not1(4)

第一块不是1的f_not1(4)


f(5)

f_not1(6)=f(3)+f(4)

铺满3块地板的数量(第一块再铺一块3)+

铺满4块地板的数量(第一块再铺一块2)

f_1(6)=f_not1(5)                                 f(6)
…… …… ……

f_not1(n)=f(n-3)+f(n-2)

铺满n-3块地板的数量(第一块再铺一块3)+

铺满n-2块地板的数量(第一块再铺一块2)

f_1(n)=f_not1(n-1) f(n)

参考代码

#include<stdio.h>
int f_not1(int n){
	if(n==1)return 0;
	else if(n==2)return 1;
	else if(n==3)return 2;
	else return f(n-3)+f(n-2);
} 
int f_1(int n){
	if(n==1)return 1;
	else if(n==2)return 0;
	else if(n==3)return 1;
	else return f_not1(n-1);
} 
int f(int n){
	return f_not1(n)+f_1(n);
}
int main(){
	int result;
	int n;
	scanf("%d",&n);
	result=f(n);
	printf("%d",result);
	return 0;
}

第一种

输入格式

只有一个数 N,代表地板的长度。

输出格式

每行一个方案,最后一行有一个数,代表方案总数。

样例输入

4

样例输出

4=1+2+1

4=1+3

4=2+2

4=3+1

4

第一块不是1 第一块是1                    第一块是2 第一块是3
not1(1)=0 is1(1)=1                           is2(1)=0 
is3(1)=0
not1(2)=1

is1(2)=0=not1(1)          

第一块不是1的1

is2(2)=1 
is3(2)=0

not1(3)=2=is2(3)+is3(3)

第一块不是3,

则是第一块是2和第一块是3的和

is1(3)=1=not1(2)            

第一块不是1的2

is2(3)=1=f(1) 

第一块是2,则还需铺满1

is3(3)=1
not1(4)=f(1)+f(2)=is2(4)+is3(4)

is1(4)=not1(3)               

第一块不是1的3

is2(4)=f(2)

第一块是2,则还需铺满2

is3(4)=f(1)
第一块是3,则还需铺满1
not1(5)=f(2)+f(3)=is2(4)+is3(5)

is1(5)=not1(4)                 

第一块不是1的4

is2(4)=f(3)
第一块是2,则还需铺满3
is3(5)=f(2)
第一块是3,则还需铺满2
…… …… …… ……
not1(n)=f(n-3)+f(n-2)=is2(n)+is3(n)
is1(n)=not1(n-1)               
is2(n)=f(n-2)
第一块是2,则还需铺满n-2
is3(n)=f(n-3)
第一块是3,则还需铺满n-3
       

输出时:先输出“”1+“”is1(n)      再输出“”2+“”is2(n)        最后输出   “”3+“”is1(3)  

比如N=4 

输出"1+"is1(4)

 is1(4)就是not1(3)、not1(3)就是is2(3)和is3(3)、is2(3)就是2+1           is3(3)就是3                   所以输出1+2+1 和1+3

#include<stdio.h>
#include<string>
#include<vector>
#include<iostream>
using namespace std;

vector<string>s[15];

int main(){
    s[1].push_back("1");
    s[2].push_back("2");
    s[3].push_back("1+2");
    s[3].push_back("2+1");
    s[3].push_back("3");

    int N;
    scanf("%d",&N);

    for(int i=4;i<=N;i++){
        for(int j=0;j<s[i-1].size();j++){
            if(s[i-1][j][0]!='1')  s[i].push_back("1+"+s[i-1][j]);//1+not1(N-1)
        }
        for(int j=0;j<s[i-2].size();j++){
            s[i].push_back("2+"+s[i-2][j]);//2+is2(N-2)
        }
        for(int j=0;j<s[i-3].size();j++){
            s[i].push_back("3+"+s[i-3][j]);//3+is3(N-3)
        }
    }
    for(int i=0;i<s[N].size();i++){
        cout<<N<<"="<<s[N][i]<<endl;
    }
    printf("%d\n",s[N].size());
	return 0;
}

转载自原文链接, 如需删除请联系管理员。

原文链接:【备战蓝桥杯】【动态规划】【 瓷砖铺放2】,转载请注明来源!

0