刷题总结——pole(uva 1638 dp)

题目:

题解:

  这道题很妙的一点是很好地利用了最矮的杆子除了放两侧以外对观察数是没有影响的性质··

  考虑n-1个杆子与n个杆子··我们可以把n个杆子的排列看成n-1个杆子的长度加1按原来的排列顺序··然后往其中加入一个长度为1的杆子··

  所以分长度为1的杆子放左右两边和放中间三种情况转移即可···

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<string>
#include<cstring>
#include<algorithm> 
using namespace std;    
long long f[205][205][205];  
int n,l,r;
const long long mod=998244353;
inline int R()
{
  char c;int f=0;
  for(c=getchar();c<'0'||c>'9';c=getchar());
  for(;c<='9'&&c>='0';c=getchar())  f=(f<<3)+(f<<1)+c-'0';
  return f;
}  
inline void pre()  
{  
  f[1][1][1]=1;  
  for(int i=2;i<=200;i++)  
    for(int j=1;j<=i;j++)  
      for(int k=1;k<=i;k++)  
        if(j+k>=3&&j+k<=i+1)  
          f[i][j][k]=((f[i-1][j-1][k]+f[i-1][j][k-1])%mod+f[i-1][j][k]*(i-2)%mod)%mod;  
}  
  
int main()  
{  
  //freopen("pole.in","r",stdin);
  freopen("pole.out","w",stdout);
  pre();  
  int T;T=R();
  while(T--)  
  {  
    n=R(),l=R(),r=R();
    cout<<f[n][l][r]<<endl; 
  }  
  return 0;  
} 

 

posted @ 2017-10-23 19:55  AseanA  阅读(215)  评论(0编辑  收藏  举报