1638 - Pole Arrangement (递推)

来源:互联网 发布:悠百佳怎么样知乎 编辑:程序博客网 时间:2024/05/22 15:10

该题用到了DP的思想,递推出所有可能情况 。

要想维护所有状态,求出要求的情况,那么显然要维护三个量:几根杆子(DP的序)、从左边看杆子的数量、从右边看杆子的数量 。

所以状态表示也要增加相应的维度,用d[i][j][k]表示前i根杆子,从左边看有j根,从右边看有k根的可能情况 。

接下来就要想好如何转移状态了 : 当前状态肯定要依赖于上一阶段的状态,那么我们不妨想:当前状态与上一状态的不同之处是要将第i根杆子插入前i-1根杆子中,那么有几种可能情况呢? 显然是三种 : 1.插到最左边,那么从左边看杆子数加一(因为杆子是从大到小插入的)。2.插到最右边,那么右边的杆子数加一。3.插到中间,我们假设i从2开始,那么将有i-2种插法,而且不会改变从两边看到的杆子数。

第三步,确定好递推的边界 :因为i从2开始,所以它所依赖的边界是i为1时的情况,当i为1时无论从左边还是右边都只能看到一根,所以边界为d[1][1][1] = 1;其他值为0 。

另外要开long long 。

细节参见代码:

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 25;int T,n,m,l,r;ll d[maxn][maxn][maxn];int main() {    scanf("%d",&T);    while(T--) {        scanf("%d%d%d",&n,&l,&r);        memset(d,0,sizeof(d));        d[1][1][1] = 1;        for(int i=2;i<=n;i++)             for(int j=1;j<=n;j++)                 for(int k=1;k<=n;k++)                     d[i][j][k] = d[i-1][j-1][k] + d[i-1][j][k-1] + d[i-1][j][k]*(i-2);                printf("%lld\n",d[n][l][r]);    }    return 0;}


1 0
原创粉丝点击