Go: package main

import "fmt"

func main() {
	//部屋を生成
	var H int

	fmt.Scan(&H)
	room := [][4]bool{}

	for i := 0; i < H; i++ {
		room = append(room, [4]bool{})
	}

	//荷物のおけない区画を設定
	var N int
	fmt.Scan(&N)
	for i := 0; i < N; i++ {
		var x, y int
		fmt.Scan(&x, &y)
		room[y][x] = true //ものがある状態を真とする
	}

	//荷物を配置
	var count int
	for i := 0; i < H-1; i++ {
		for j := 0; j < 3; j++ {
			if !room[i][j] && !room[i+1][j] && !room[i][j+1] && !room[i+1][j+1] {
				room[i][j] = true
				room[i+1][j] = true
				room[i][j+1] = true
				room[i+1][j+1] = true
				count++
			}
		}
	}
	fmt.Println(count)
}

C++: #include<bits/stdc++.h>
using namespace std;

int H,N;
int t[100005][4];
int dp[100005][1<<4];

int main(){
  cin>>H>>N;
  for(int i=0;i<H;i++){
    int x,y;
    cin>>x>>y;
    t[x][y]=1;
  }
  
  for(int i=0;i<H;i++)
    for(int j=0;j< (1<<4);j++)
      dp[i][j]=-100000000;
  
  dp[0][0]=0;
  int ans=0;
  
  for(int i=0;i<H;i++){
  
    for(int b=0;b<(1<<4);b++){

      ans=max(ans,dp[i][b]);
      if(i==H-1)continue;
      
      int tmp[2][4]={};
      
      for(int j=0;j<4;j++){
        tmp[0][j]=t[i][j];
        tmp[1][j]=t[i+1][j];
        tmp[0][j]|=(b<<j&1);
      }

      if(!tmp[0][0]&&!tmp[0][1]&&!tmp[1][0]&&!tmp[1][1]){
        dp[i+1][3]=max(dp[i+1][3],dp[i][b]+1);
      }
      
      if(!tmp[0][1]&&!tmp[0][2]&&!tmp[1][1]&&!tmp[1][2]){
        dp[i+1][6]=max(dp[i+1][6],dp[i][b]+1);
      }
      
      if(!tmp[0][2]&&!tmp[0][3]&&!tmp[1][2]&&!tmp[1][3]){
        dp[i+1][3]=max(dp[i+1][12],dp[i][b]+1);
      }
      
      if(!tmp[0][0]&&!tmp[0][1]&&!tmp[1][0]&&!tmp[1][1]){
        if(!tmp[0][2]&&!tmp[0][3]&&!tmp[1][2]&&!tmp[1][3]){
          dp[i+1][15]=max(dp[i+1][15],dp[i][b]+2);
        }
      }
      
    }

    
  }

  cout<<ans<<endl;
  return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
/// {{{ DEBUG --- ///
#ifdef DEBUG
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { o << "{"; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; return o; }
#ifdef USE_COUT
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);cout<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\n";}()
#else
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);cerr<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\n";}()
#endif
template<class T> inline void dump2D(T &d, size_t sizey, size_t sizex) { ostream&o=
#ifdef USE_COUT
  cout;
#else
  cerr;
#endif
  for(size_t i = 0; i < sizey; i++) { for(size_t j = 0; j < sizex; j++) o << d[i][j] << " "; o << endl; }
}
#else
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); return o; }
#define dump(...) (42)
#define dump2D(...) (42)
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
/// }}}--- ///


int f[4][11234];
int h;
int n;

int dp[11234][1 << 3];

int check(int y, int x) {
  for(int i = y; i <= y + 1; i++) for(int j = x; j <= x + 1; j++) {
    if(f[j][i]) return 0;
  }
  return 1;
}

int main() {
  std::ios::sync_with_stdio(false), std::cin.tie(0);
  cin >> h;
  cin >> n;
  for(int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    f[x][y] = 1;
  }
  
  int ans = 0;
  {
    int y = 0;
    for(int i = 0; i < (1 << 3); i++) {
      int cnt = 0, no = 0;
      for(int ii = 0; ii < 3; ii++) if(i & (1 << ii)) {
        if(!check(y, ii)) no = 1;
        cnt++;
      }
      if(__builtin_popcount(i) >= 2) if(i != 5) no = 1; 
      if(no) continue;
      dp[y][i] = cnt;
      dump(y, i, cnt);
      ans = max(ans, dp[y][i]);
    }
  }

  for(int y = 0; y < h - 2; y++) {
    // yでの置き方
    for(int i = 0; i < (1 << 3); i++) {
      int no = 0;
      for(int ii = 0; ii < 3; ii++) if(i & (1 << ii)) {
        if(!check(y, ii)) no = 1;
      }
      if(__builtin_popcount(i) >= 2) if(i != 5) no = 1; 
      if(no) continue;
      // y + 1での置き方
      for(int j = 0; j < (1 << 3); j++) {
        int cnt = 0, no = 0;
        for(int ii = 0; ii < 3; ii++) if(j & (1 << ii)) {
          if(!check(y + 1, ii)) no = 1;
          cnt++;
        }
        if(__builtin_popcount(j) >= 2) if(j != 5) no = 1; 
        for(int ii = 0; ii < 3; ii++) for(int jj = 0; jj < 3; jj++) 
          if(i&(1 << ii)) if(j &(1<<jj)) {
            if(abs(ii - jj) <= 1) no = 1;
          }
        if(no) continue;
        dp[y+1][j] = max(dp[y+1][j], dp[y][i] + cnt);
        ans = max(ans, dp[y + 1][j]);
      }
    }
  }
  cout << ans << endl;
  return 0;
}