1. 程式人生 > >OpenJ_Bailian 4103 踩方格(搜索 動態規劃 )

OpenJ_Bailian 4103 踩方格(搜索 動態規劃 )

include 轉移 div spa pen ref 向上 opened .cn

題目傳送門OpenJ_Bailian 4103

描述

有一個方格矩陣,矩陣邊界在無窮遠處。我們做如下假設:
a. 每走一步時,只能從當前方格移動一格,走到某個相鄰的方格上;
b. 走過的格子立即塌陷無法再走第二次;
c. 只能向北、東、西三個方向走;
請問:如果允許在方格矩陣上走n步,共有多少種不同的方案。2種走法只要有一步不一樣,即被認為是不同的方案。

輸入

允許在方格上行走的步數n(n <= 20)

輸出

計算出的方案數量

樣例輸入

2

樣例輸出

7



解題思路:

   1.遞歸:從 (i,j) 出發,走n步的方案數,等於以下三項之和:

      從(i+1,j)出發,走n-1步的方案數。前提:(i+1,j)還沒走過

    從(i,j+1)出發,走n-1步的方案數。前提:(i,j+1)還沒走過

    從(i,j-1)出發,走n-1步的方案數。前提:(i,j-1)還沒走過

      逐層往下搜。

    或者用狀態轉移:

    要是最後一步是向左走,則前一步不能為向右走 l[i]=l[i-1]+u[i-1]

    要是最後一步是向右走,則前一步不能為向左走   r[i]=r[i-1]+u[i-1]

    要是最後一步是向上走,則前一步是什麽無影響  u[i]=l[i-1]+r[i-1]+u[i-1]

可得公式:f[i]=l[i]+r[i]+u[i]
         =2*l[i-1]+2*r[i-1]+3*u[i-1]
         =2*f[i-1]+u[i-1]
          =2*f[i-1]+f[i-2]

技術分享圖片
#include<cstdio>
int vis[30][30]= {0};
int ways(int x,int y,int n)
{
    if (n==0)
        return 1;
    vis[x][y]=1;
    int num=0;
    if (!vis[x][y-1]) num+=ways(x,y-1,n-1);
    if (!vis[x][y+1]) num+=ways(x,y+1,n-1);
    if (!vis[x+1][y]) num+=ways(x+1,y,n-1);
    vis[x][y]=0;
    return num;
}
int main() { int n; scanf("%d",&n); printf("%d\n",ways(0,22,n)); return 0; }
遞歸搜索 技術分享圖片
#include<cstdio>
int l[25],r[25],u[25];
int main()
{
    int n;
    scanf("%d",&n);
    l[1]=r[1]=u[1]=1;
    for (int i=2; i<=n; i++)
    {
        l[i]=l[i-1]+u[i-1];
        r[i]=r[i-1]+u[i-1];
        u[i]=l[i-1]+r[i-1]+u[i-1];
    }
    printf("%d\n",l[n]+u[n]+r[n]);
    return 0;
}
DP 技術分享圖片
#include<stdio.h>
int f[22];
int main()
{
    int n;
    scanf("%d",&n);
    f[1]=3,f[2]=7;
    for (int i=3; i<=n; i++)
        f[i]=2*f[i-1]+f[i-2];
    printf("%d\n",f[n]);
    return 0;
}
公式

OpenJ_Bailian 4103 踩方格(搜索 動態規劃 )