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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[CEOI2016] kangaroo(排列dp)

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [CEOI2016] kangaroo(排列dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

problem

luogu-P5999

solution

每個點只能跳一次,顯然跳出來形成的順序是一個排列。不難聯想到最近刷的排列 dpdpdp

然后,我覺得難點在于怎么轉化這個跳的規則,因為現在并不確定能否按排列 dpdpdp 一樣分段做。

跳的順序形成的排列必須滿足以下兩個條件之一:

  • 排列中第 iii 個元素必須小于兩邊的元素。
  • 排列中第 iii 個元素必須大于兩邊的元素。

排列的起終點(墻)為 s,ts,ts,t

轉化后發現,這是可以排列 dpdpdp 的。

我們從小到大考慮 iii。設 f(i,j):f(i,j):f(i,j):iii 個數將排列分成了 jjj 段的合法方案數。

  • iii 不是墻。

    • 合并兩段,jjj 段有 j?1j-1j?1 個空。f(i,j)←f(i?1,j+1)?jf(i,j)\leftarrow f(i-1,j+1)*jf(i,j)f(i?1,j+1)?j

    • 新插一段,可以插在任何位置,但若 sss 已過則不能插首,若 ttt 已過則不能插尾。

      f(i,j)←f(i?1,j?1)?(j?(i>s)?(i>t))f(i,j)\leftarrow f(i-1,j-1)*\big(j-(i>s)-(i>t)\big)f(i,j)f(i?1,j?1)?(j?(i>s)?(i>t))

  • iii 是墻。只能放在首尾。

    • 單獨成段。f(i,j)←f(i?1,j?1)f(i,j)\leftarrow f(i-1,j-1)f(i,j)f(i?1,j?1)
    • 與相鄰段合并,相當于延伸。f(i,j)←f(i?1,j)f(i,j)\leftarrow f(i-1,j)f(i,j)f(i?1,j)

時間復雜度 O(n2)O(n^2)O(n2)

code

#include <bits/stdc++.h> using namespace std; #define int long long #define mod 1000000007 #define maxn 2005 int f[maxn][maxn]; int n, s, t;signed main() {scanf( "%lld %lld %lld", &n, &s, &t );f[1][1] = 1;for( int i = 2;i <= n;i ++ )if( i ^ s and i ^ t )for( int j = 1;j <= n;j ++ )f[i][j] = (f[i - 1][j - 1] * (j - (i > s) - (i > t) ) + f[i - 1][j + 1] * j) % mod;elsefor( int j = 1;j <= n;j ++ )f[i][j] = (f[i - 1][j - 1] + f[i - 1][j]) % mod; printf( "%lld\n", f[n][1] );return 0; }

總結

以上是生活随笔為你收集整理的[CEOI2016] kangaroo(排列dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

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