0w1

ARC 074 E - RGB Sequence ( DP )

E: RGB Sequence - AtCoder Regular Contest 074 | AtCoder

題意:
N 個格子一排。
有三種顏色可以塗。
M 條限制,表示 [ L, R ] 中要有 X 種顏色。
求方案數模 1e9 + 7。

制約:
1≤N≤300
1≤M≤300
1≤li≤ri≤N
1≤xi≤3

解法:
dp[ i ][ j ][ k ]:第 { 1, 2, 3 } 種顏色最後出現的位置 { i, j, k },此時的方案數。
有這狀態就能知道合不合限制。當 max{ i, j, k } 和某個限制的 R 一致的時候檢查。

複雜度:
O( N ** 3 + N ** 2 * M )

#include <bits/stdc++.h>
using namespace std;
 
const int MOD = int( 1e9 ) + 7;
 
const int MAXN = 300;
const int MAXM = 300;
 
int N, M;
int L[ MAXM ], R[ MAXM ], X[ MAXM ];
vector< pair< int, int > > r2lx[ MAXN + 1 ];
 
int dp[ MAXN + 1 ][ MAXN + 1 ][ MAXN + 1 ];
 
signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M;
  for( int i = 0; i < M; ++i ) {
    cin >> L[ i ] >> R[ i ] >> X[ i ];
    r2lx[ R[ i ] ].emplace_back( L[ i ], X[ i ] );
  }
  dp[ 0 ][ 0 ][ 0 ] = 1;
  for( int i = 0; i <= N; ++i ) {
    for( int j = 0; j <= N; ++j ) {
      for( int k = 0; k <= N; ++k ) {
        for( auto lx: r2lx[ max( { i, j, k } ) ] ) {
          int l, x; tie( l, x ) = lx;
          if( ( l <= i ) + ( l <= j ) + ( l <= k ) != x ) {
            dp[ i ][ j ][ k ] = 0;
          }
        }
        if( max( { i, j, k } ) == N ) continue;
        if( dp[ i ][ j ][ k ] == 0 ) continue;
        ( dp[ max( { i, j, k } ) + 1 ][ j ][ k ] += dp[ i ][ j ][ k ] ) %= MOD;
        ( dp[ i ][ max( { i, j, k } ) + 1 ][ k ] += dp[ i ][ j ][ k ] ) %= MOD;
        ( dp[ i ][ j ][ max( { i, j, k } ) + 1 ] += dp[ i ][ j ][ k ] ) %= MOD;
      }
    }
  }
  int ans = 0;
  for( int i = 0; i < N; ++i ) {
    for( int j = 0; j < N; ++j ) {
      ( ans += dp[ N ][ i ][ j ] ) %= MOD;
      ( ans += dp[ i ][ N ][ j ] ) %= MOD;
      ( ans += dp[ i ][ j ][ N ] ) %= MOD;
    }
  }
  cout << ans << endl;
  return 0;
}