UVa 1638 Pole Arrangement (动态规划)

题目

题目大意

有高为\(1, 2, 3,···,n\)的杆子各一根排成一行, 从左边能看到\(l\)根, 从右边能看到\(r\)根, 求有多少种可能。

题解

因为所有杆子的高度都不一样, 我们假设\(2\)~\(i\)所有杆子已经安排上了放好了(每次只考虑最矮的一根), 那么有三种情况:

  1. 放在最左边, 只能从左边看到它
  2. 放在最右边, 只能从右边看到它
  3. 放在中间, 两边都看不到它, 因为中间有\(i - 2\)个位置可以放, 因此有\(i - 2\)种情况

依次可以得到状态转移方程:

\[d(i, j, k) = d(i - 1, j - 1, k) + d(i - 1, j, k - 1) + d(i - 1, j, k) * (i - 2) \]

代码
#include <cstdio>
unsigned long long dp[30][30][30];
int T, n, l, r;
int main(int argc, char const *argv[]) {
  dp[1][1][1] = 1;
  for (register unsigned long long i(2); i <= 20; ++i) {
    for (register unsigned long long j(1); j <= i; ++j) {
      for (register unsigned long long k(1); k <= i; ++k) {
        dp[i][j][k] = dp[i - 1][j - 1][k] + dp[i - 1][j][k - 1] + dp[i - 1][j][k] * (i - 2);
      }
    }
  }
  scanf("%d", &T);
  while (T--) {
    scanf("%d %d %d", &n, &l, &r);
    printf("%llu\n", dp[n][l][r]);
  }
  return 0;
}

转载于:https://www.cnblogs.com/forth/p/9722090.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值