Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
	)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	for scanner.Scan() {
		buf := strings.Split(scanner.Text(), " ")
		X, _ := strconv.Atoi(buf[0])
		Y, _ := strconv.Atoi(buf[1])
		if X == 0 && Y == 0 {
			break
		}
		tbl := make([][]int, Y+2)
		field := make([][]int, Y+2)
		for i := range field {
			field[i] = make([]int, X+2)
			tbl[i] = make([]int, X+2)
			for j := range field[i] {
				field[i][j] = 2
				tbl[i][j] = 0
			}
		}
		buf_ := make([][]string, Y)
		for i := range buf_ {
			scanner.Scan()
			buf_[i] = strings.Split(scanner.Text(), " ")
		}
		for i := 1; i <= Y; i++ {
			for j := 1; j <= X; j++ {
				field[i][j], _ = strconv.Atoi(buf_[i-1][j-1])
				switch field[i][j] {
				case 0:
					if i == 1 {
						tbl[i][j] = 1 // スタートy=1
					} else {
						if field[i-1][j-1] != 2 {
							tbl[i][j] += tbl[i-1][j-1] // 左上からやってくる
						}
						if field[i-1][j] != 2 {
							tbl[i][j] += tbl[i-1][j] // 真上からやってくる
						}
						if field[i-1][j+1] != 2 {
							tbl[i][j] += tbl[i-1][j+1] // 右上からやってくる
						}
						if field[i-2][j] == 2 {
							tbl[i][j] += tbl[i-2][j] // ジャンプしてくる
						}
					}
				case 1:
					tbl[i][j] = 0 // 障害物あり
				case 2:
					if field[i-1][j] != 2 {
						tbl[i][j] += tbl[i-1][j] // 真上からくる
					}
					if field[i-2][j] == 2 {
						tbl[i][j] += tbl[i-2][j] // ジャンプ台からジャンプしてくる
					}
				}
			}
		}
		sum := 0
		for i := 1; i <= X; i++ {
			sum += tbl[Y][i] // とびこさないでゴール
			if field[Y-1][i] == 2 {
				sum += tbl[Y-1][i] // 飛び越してゴール
			}
		}
		fmt.Println(sum)
	}
}

C++: #include <bits/stdc++.h>

typedef struct {
    int y;
    int x;
    int x_temp;
    int end;
    int ans;
} Ski_data; 

int ski_resort[16][17];

Ski_data* ski_ans(Ski_data* ski_data_ptr) 
{
    bool retire_flag = false;

    while (ski_data_ptr->y <= (ski_data_ptr->end + 1) && !retire_flag) {
        std::cout << "(y, x) : "  << ski_data_ptr->y << " " << ski_data_ptr->x << std::endl;

        switch (ski_resort[ski_data_ptr->y][ski_data_ptr->x]) {
            
            case 0:
                ski_data_ptr->y += 1;
                for (int i = -1; i <= 1; ++i) {
                    int temp_x = ski_data_ptr->x;
                    int temp_y = ski_data_ptr->y;
                    ski_data_ptr->x += i;

                    ski_ans(ski_data_ptr);

                    if ( i <= 0) {
                        ski_data_ptr->x = temp_x;
                        ski_data_ptr->y = temp_y;
                    } else {
                        retire_flag = true;
                    }
                }
                
                break;
            case 1:
                retire_flag = true;
                break;
            case 2:
                if (ski_data_ptr-> y <= ski_data_ptr->end)
                ski_data_ptr->y += 2;
                break;
            case 3:
                ski_data_ptr->ans += 1;
                //std::cout << "ski_data_ptr->ans : " << ski_data_ptr->ans << std::endl;
                retire_flag = true;
                break;
            default:
                break;
        }
    }
    return ski_data_ptr;
}

int main(void)
{
    int ski_height, ski_width;
    bool half_flag = false;
    
    while (std::cin >> ski_width >> ski_height) {
        if (!ski_width && !ski_height) {
            break;
        }

        for (int y = 0; y < ski_height; ++y) {
            for (int x = 1; x < ski_width + 1; ++x) {
                std::cin >> ski_resort[y][x];
                if (ski_resort[y][x] != 0) {
                    half_flag = true;
                }
            }
        }

        for (int y = 0; y < ski_height; ++y){
            ski_resort[y][0] = ski_resort[y][ski_width + 1] = 1;
        }

        for (int x = 1; x < ski_width + 1; ++x) {
            if (ski_resort[ski_height - 1][x] != 1){
                ski_resort[ski_height - 1][x] = 3;
            }
        }

        for (int x = 0; x < ski_width + 2; ++x) {
            if (x == 0 || x == ski_width + 1) {
                ski_resort[ski_height][x] = 1;
            } else {
                ski_resort[ski_height][x] = 3;
            }
        }

        int ans = 0;
        
        for (int x = 1; x < ski_width + 1; ++x) {
            Ski_data ski_data = {0, x, 0, ski_height - 1, 0};

            ans += ski_ans(&ski_data)->ans;
            
            /*std::cout << "ski_data->ans : " << ski_data.ans 
                      << " ans : " << ans << std::endl;
            */
        }

        std::cout << ans / (half_flag ? 2 : 1) << std::endl;

        /*
        for (int y = 0; y < ski_height + 1; ++y) {
            for (int x = 0; x < ski_width + 2; ++x) {
                std::cout << ski_resort[y][x];
            }
            std::cout << std::endl;
        }
        */
    }
    
    return 0;
}

C++: #include <iostream>
using namespace std;
int w,h;
int mp[20][20],memo[20][20];
void saiki(int x,int y){
  if(y >= h-1) memo[y][x]++;
  else {
    for(int i=-1;i<=1;i++) {
      int nx = x+i, ny = y+1;
      if(nx==x && mp[ny][nx] == 2)while(mp[ny][nx] == 2) ny+=2;
      if(nx <0|| nx >= w ||mp[ny][nx] == 1) continue;

      if(memo[ny][nx]>0) memo[y][x] += memo[ny][nx];
      else saiki(nx,ny),memo[y][x] += memo[ny][nx];

    }
    if(memo[y][x] == 0) mp[y][x] = 1;
  }
}
int main() {
  while(1) {
    cin >> w >> h;
    if(w == 0 && h == 0) break;
    for(int i=0;i<=19;i++)
      for(int j=0;j<=19;j++)memo[i][j] = mp[i][j] = 0;
     
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)cin >> mp[i][j];
  
    for(int i=0;i<w;i++)
      if(mp[0][i] !=1) saiki(i,0);
     
    int cnt = 0;
    for(int i=0;i<w;i++)cnt+=memo[0][i];
    cout <<cnt<<endl;
  }
  return 0;
}

C++: #include<stdio.h>

int dx[3] = {-1, 0, 1};
int dy[3] = {1, 1, 1};

int main(void)
{
	int **map, f1, f2, f3, **temp, x, y, sum, px, py;
	
	while(scanf("%d %d", &x, &y) && y > 0)
	{
		map = new int *[y];
		temp = new int *[y];
		sum = 0;

		//マップ土地&動的計画作成
		for(f1 = 0; f1 < y; f1++)
		{
			map[f1] = new int [x];
			temp[f1] = new int [x];
		}
		//マップ構成入力&初期化
		for(f1 = 0; f1 < y; f1++)
		{
			for(f2 = 0; f2 < x; f2++)
			{
				scanf("%d",&map[f1][f2]);
				temp[f1][f2] = 0;
			}
		}
		//最上のスタート地点設定
		for(f1 = 0; f1 < x; f1++)
		{
			if(map[0][f1] != 1)
			{
				temp[0][f1] = 1;
				sum++;
			}
		}
		//探索
		if(y >= 2)
		{
			sum = 0;
			for(f1 = 0; f1 < y - 1; f1++)
			{
				for(f2 = 0; f2 < x; f2++)
				{
					if(map[f1][f2] == 0 && temp[f1][f2] > 0)
					{
						for(f3 = 0; f3 < 3; f3++)
						{
							//移動
							px = f2 + dx[f3];
							py = f1 + dy[f3];
							//範囲内か
							if(px >= 0 && px < x)
							{
								//同じｘ座標からのジャンプ台
								if(f3 == 1 && py < y - 1){
									//ｙ軸2つ先へ
									while(py <= y - 1 && map[py][px] == 2)
										py += 2;
								}
								//着地した場所がゴール地点のｙ座標と同じで障害物にぶつかってないか
								//ゴール地点のｙ座標を超えたか
								if(py > y - 1 || py == y - 1 &&(f3 != 1 && map[py][px] == 0 || f3 == 1 && map[py][px] != 1))
									sum += temp[f1][f2];
								//超えてないが、障害物がない地点に着地したか
								else if(map[py][px] == 0)
									temp[py][px] += temp[f1][f2];
							}
						}
					}
				}
			}
		}
		//出力
		printf("%d\n",sum);
	}

	return 0;
}