日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计数原理,递推,求从左边能看到l个棒子,右边能看到r个棒子的方案数目

發(fā)布時間:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计数原理,递推,求从左边能看到l个棒子,右边能看到r个棒子的方案数目 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題意

有高為 1, 2, …, n 的 n 根桿子排成一排, 從左向右能看到 L 根, 從右向左能看到 R 根。求有多少種可能的排列方式。

solution:

數(shù)據(jù)范圍僅200,本來是往組合數(shù)學方面想的,看到了這個200就放棄了念頭,果然是dp

定義dp[i][j][k]是用了高度為1~i的桿子,從左邊能看到j個,從右邊能看到k個

如果從1轉移到n很困難,因為放一個高的桿子進去會造成很多的遮擋影響,是幾乎不能維護的。于是考慮從n轉移到1,即先放比較高的桿子

加上放好了2~n高度的桿子,再放高度為1的桿子僅有三種情況

1.放在最左邊。僅僅是從左看能多看到一個 dp[i][j][k]+=dp[i-1][j-1][k]

2.放在最右邊,同理

3.放在中間,一定會被擋住。i-1根桿子間有(i-2)個,則dp[i][j][k]+=dp[i-1][j][k]*(i-2)。

其實這里i的定義已經(jīng)發(fā)生了一點變化,但是狀態(tài)轉移是很容易理解的

為什么可以把i等效定義為i個,而不是1~i呢?其實這只需要代表是i根高度不同的桿子,2~i的桿子全部砍1,相對高度沒有變,也就等效成了1~i-1的桿子

1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<cstring> 7 #define mp make_pair 8 #define pb push_back 9 #define first fi 10 #define second se 11 #define pw(x) (1ll << (x)) 12 #define sz(x) ((int)(x).size()) 13 #define all(x) (x).begin(),(x).end() 14 #define rep(i,l,r) for(int i=(l);i<(r);i++) 15 #define per(i,r,l) for(int i=(r);i>=(l);i--) 16 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 17 #define eps 1e-9 18 #define PIE acos(-1) 19 #define cl(a,b) memset(a,b,sizeof(a)) 20 #define fastio ios::sync_with_stdio(false);cin.tie(0); 21 #define lson l , mid , ls 22 #define rson mid + 1 , r , rs 23 #define ls (rt<<1) 24 #define rs (ls|1) 25 #define INF 0x3f3f3f3f 26 #define LINF 0x3f3f3f3f3f3f3f3f 27 #define freopen freopen("in.txt","r",stdin); 28 #define cfin ifstream cin("in.txt"); 29 #define lowbit(x) (x&(-x)) 30 #define sqr(a) a*a 31 #define ll long long 32 #define ull unsigned long long 33 #define vi vector<int> 34 #define pii pair<int, int> 35 #define dd(x) cout << #x << " = " << (x) << ", " 36 #define de(x) cout << #x << " = " << (x) << "\n" 37 #define endl "\n" 38 using namespace std; 39 //********************************** 40 ll dp[25][25][25];//dp[i][j][k]表示i個棒子從左邊能看到j個右邊能看到k個的方案數(shù) 41 //********************************** 42 void Init() 43 { 44 dp[1][1][1]=1; 45 FOR(i,2,20)FOR(j,1,i)FOR(k,1,i-j+1)dp[i][j][k]=dp[i-1][j-1][k]+dp[i-1][j][k-1]+dp[i-1][j][k]*(i-2); 46 } 47 //********************************** 48 int main() 49 { 50 Init(); 51 int T;cin>>T; 52 while(T--){ 53 int a,b,c;cin>>a>>b>>c; 54 cout<<dp[a][b][c]<<endl; 55 } 56 return 0; 57 } View Code

?

轉載于:https://www.cnblogs.com/klaycf/p/9689467.html

總結

以上是生活随笔為你收集整理的计数原理,递推,求从左边能看到l个棒子,右边能看到r个棒子的方案数目的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。