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 j := 0; j < H-1; j++ {
		for i := 0; i < 3; i++ {

			if !room[j][i] && !room[j+1][i] && !room[j][i+1] && !room[j+1][i+1] {
				//if i!=0&&i!=2&&j!=H-3{
				//	if !room[j+1][i-1]&&!room[j+1][i+2]{
				//		if !room[j+2][0]&&!room[j+2][1]&&!room[j+2][2]&&!room[j+2][3]{
				//			break
				//		}
				//	}
				//}
				room[j][i] = true
				room[j+1][i] = true
				room[j][i+1] = true
				room[j+1][i+1] = true
				count++
			}
		}
	}

	var openCount int
	for _,v:=range room{
		openCount=0
		for _,v2:=range v{
			if !v2{
				openCount++
			}

		}
		if openCount>=3{
			count++
		}
	}
	fmt.Println(count)
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include<random>
#include<math.h>
#include<limits.h>
#include<iterator>
#include<queue>
#include<functional>
#define rep(i,a) for(int i=0;i<a;i++)
#define nrep(i,a,b) for(int i=a;i<b;i++)
#define mrep(i,a) for(int i=a;i>=0;i--)
#define ll long long
#define vl vector<ll> 
#define vvl vector<vector<ll> > 
#define vb vector<bool> 
#define vvb vector<vector<bool> > 
#define INF 11234567890123456789
using namespace std;

int main(){
	ll h, n; cin >> h >> n;
	vvb map(4, vb(h, true));
	rep(i, n){
		ll x, y; cin >> x >> y;
		map[x][y] = false;
	}
	vl dp(h, 0);
	ll count = 0;
	rep(i, h-1){
		vb map_b(3);
		ll plus = 0;
		if (i > 0) plus = dp[i - 1];
		rep(j, 3) if (map[j][i] && map[j][i + 1] && map[j+1][i] && map[j+1][i + 1]) map_b[j] = true;
		if (map_b[0] && map_b[2]) dp[i + 1] = 2 + plus;
		else if (map_b[0] || map_b[1] || map_b[2]) dp[i + 1] = 1 + plus;
		else dp[i + 1] = plus;
	}cout << dp[h - 1] << endl;
	return 0;
}

C++: #include <bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

bool b[10000][4];
int dp[20000][1<<4];
int main(){
	int h,n;scanf("%d%d",&h,&n);
	rep(i,n){
		int x,y;scanf("%d%d",&y,&x);
		b[h-x-1][y]=true;
	}
	rep(i,h-1)rep(j,1<<4){
		dp[i+1][0]=max(dp[i+1][0],dp[i][j]);
		rep(k,3){
			if(!(j>>k&1)&&!(j>>(k+1)&1)&&!b[i][k]&&!b[i][k+1]&&!b[i+1][k]&&!b[i+1][k+1]){
				dp[i+1][(1<<k)|(1<<(k+1))]=max(dp[i+1][(1<<k)|(1<<(k+1))],dp[i][j]+1);
			}
		}
		if(j==0){
			bool flag=true;
			rep(k,2)rep(t,4){
				if(b[i+k][t]==1)flag=false;
			}
			if(flag){
				dp[i+1][(1<<4)-1]=max(dp[i+1][(1<<4)-1],dp[i][j]+2);
			}
		}
	}
	int ans=0;
	rep(i,1<<4){
		ans=max(ans,dp[h-1][i]);
	}
	cout<<ans<<endl;
}

C++: #include <stdio.h>
#define MAX_H 100000
int blocked[MAX_H];
int dp[2][1<<4];
main() {
 int h, n; scanf("%d %d", &h, &n);
 int x, y;
 for ( int i=0; i<n; ++i ) {
scanf("%d %d", &x, &y); blocked[y] |= 1<<x;
 }
 int locate[5] = { 0x0, 0x3, 0x6, 0xc, 0xf };//置き方パターン
 int add[5] = { 0, 1, 1, 1, 2 };//各置き方パターンで置ける個数

 int* crt = dp[0];
 int* next = dp[1];

 for ( int obstacle=0; obstacle<1<<4; ++obstacle ) {
if ( obstacle&blocked[0] ) crt[obstacle] = -1;
else crt[obstacle] = 0;
 }

 for ( int i=0; i<h-1; ++i ) {
std::fill( next, next+(1<<4), -1 );
for ( int obstacle=0; obstacle<1<<4; ++obstacle ) {//既に有るものパターン(current)
 if ( crt[obstacle] == -1 ) continue;
 for ( int k=0; k<5; ++k ) {//置き方パターン(next)
int check0 = blocked[i] & locate[k];
int check1 = blocked[i+1] & locate[k];
if ( !check0 && !check1 && !(obstacle&locate[k])) {
 int patt = blocked[i+1] | locate[k];
 next[patt] = std::max( crt[obstacle] + add[k], next[patt] );
}
 }
}
int* tmp = crt;
crt = next;
next = tmp;
 }
 int res = 0;
 for ( int i=0; i<1<<4; ++i ) if ( next[i] > res ) res = next[i];
 printf("%d¥n", res );
}

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;
}