UVa 1638-Pole Arrangement

来源:互联网 发布:老虎机js代码 编辑:程序博客网 时间:2024/05/03 05:06


小结:

因为这个分类是分类在递推中的,所以想法理所当然应该往递推的方向去走,首先能想到的是从低到高依次摆放杆子,不过尝试过就知道了,做法远比想象中复杂,然后就尝试了下依次从高往低排,视野一下子就开阔了。

然后就是怎么实现递推了,令f(i,j,k)代表从左边看有i根杆子,从右边看有j根杆子,已经放置的杆子有k根的情况,由于,看到的杆子的根数只和杆子的相对高度有关,而和杆子的绝对高度无关。那么,当放入一根比已有的杆子长度都短的杆子时,只可能有3种情况:

(1)杆子放在所有杆子的最左端,造成的结果是从左边可以看见的杆子数加1,而从右边能看见的杆子数目不变。

(2)杆子放在所有杆子的最右端,造成的结果是从右边可以看见的杆子数加1,而从左边能看见的杆子数目不变。

(3)杆子放在任意中间位置,由于放入的杆子比所有的杆子的高度要低,所以从左,右两边能看见得杆子数目不变。

因此,

递推方程为:f(i,j,k)=f(i-1,j,k-1)+f(i,j-1.k)+f(i,j,k-1)

以下是AC代码:

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<malloc.h>using namespace std;typedef long long ll;ll  recur[50][50][50];int main(){    int n,l,r;    int t;    scanf("%d",&t);    for(int m=1;m<=t;m++)    {        scanf("%d%d%d",&n,&l,&r);        memset(recur,0,sizeof(recur));        recur[1][1][1]=1;        recur[2][1][2]=1;        recur[1][2][2]=1;        for(int i=3;i<=n;i++)        {            for(int j=1;j<=l;j++)            for(int k=1;k<=r;k++)            {                if(j==1&&k==1)                continue;                recur[j][k][i]=recur[j-1][k][i-1]+recur[j][k-1][i-1]+recur[j][k][i-1]*(i-2);            }        }        printf("%lld\n",recur[l][r][n]);    }    return 0;}



0 0
原创粉丝点击