hdu 5151 Sit sit sit(DP)

题目链接:hdu 5151 Sit sit sit

区间dp,dp[i][j]表示从i到j的方案数,每次枚举i~j之间放最大值的位置,左右颜色不同的位置不能放最大值。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 105;
typedef long long ll;
const ll mod = 1e9+7;

int N, v[maxn];
ll dp[maxn][maxn], C[maxn][maxn];

void init (int n) {
	for (int i = 0; i <= n; i++) {
		C[i][0] = C[i][i] = 1;
		for (int j = 1; j < i; j++)
			C[i][j] = (C[i-1][j-1] + C[i-1][j]) % mod;
	}
}

int solve() {
	memset(dp, 0, sizeof(dp));
	for (int i = 1; i <= N; i++)  dp[i][i] = 1;
	for (int len = 1; len < N; len++) {
		for (int l = 1; l + len <= N; l++) {
			int r = l + len;
			for (int k = l; k <= r; k++) {
				if (k == l)
					dp[l][r] = (dp[l][r] + dp[k+1][r]) % mod;
				else if (k == r)
					dp[l][r] = (dp[l][r] + dp[l][k-1]) % mod;
				else if (v[k-1] == v[k+1])
					dp[l][r] = (dp[l][r] + dp[l][k-1] * dp[k+1][r] % mod * C[r-l][k-l] % mod) % mod;
			}
		}
	}
	return dp[1][N];
}

int main () {
	init(100);
	while (scanf("%d", &N) == 1) {
		for (int i = 1; i <= N; i++)
			scanf("%d", &v[i]);
		printf("%d\n", solve());
	}
	return 0;
}


你可能感兴趣的:(hdu 5151 Sit sit sit(DP))