HDU 5151 Sit sit sit
区间DP+组合计数问题,转移方程为,每次选当前区间最后一个放的位置,然后乘上组合数C[区间长度][左区间长度]
代码:
#include <cstdio> #include <cstring> typedef long long ll; const ll MOD = 1000000007; const int N = 105; int n, a[N]; ll dp[N][N], C[N][N]; int main() { C[1][0] = C[1][1] = 1; for (int i = 2; i <= 100; i++) { C[i][0] = C[i][i] = 1; for (int j = 1; j < i; j++) { C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD; } } while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) scanf("%d", &a[i]); 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 (l == k) dp[l][r] = (dp[l][r] + dp[k + 1][r]) % MOD; else if (r == k) dp[l][r] = (dp[l][r] + dp[l][k - 1]) % MOD; else if (a[k - 1] == a[k + 1]) dp[l][r] = (dp[l][r] + (dp[l][k - 1] * dp[k + 1][r] % MOD * C[r - l][k - l]) % MOD) % MOD; } } } printf("%lld\n", dp[1][n]); } return 0; }
时间: 2024-10-12 23:22:43