1. 程式人生 > >刷題總結——pole(uva 1638 dp)

刷題總結——pole(uva 1638 dp)

ges iostream etc log get .cn stdout n-1 blog

題目:

技術分享

題解:

這道題很妙的一點是很好地利用了最矮的桿子除了放兩側以外對觀察數是沒有影響的性質··

考慮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; }

刷題總結——pole(uva 1638 dp)