嘟嘟嘟
這道題dp雖然不難,但是我還是沒推出來,感覺最近腦子不太好用啊。
於是就跑去問神仙gjx(全國前三!)了。(外出集訓真是好)
神仙不愧是神仙,一會兒就想出來了,而且方法還比網上的題解好懂。
dp[i][j]表示用值域為[1, i]的數,湊出的所有合法序列的值的和。
然後規定序列必須是嚴格遞增的,這樣答案再乘以乙個\(n!\)就行了。
轉移的時候,我們考慮\(i\)這個數用不用上,於是有:\(dp[i][j] = dp[i - 1][j] +i * dp[i - 1][j - 1]\)。現在感覺這個挺好理解的,如果用上\(i\)了,\(i\)就必須放在最後面,並且答案要乘以\(i\)。
但這個複雜度\(o(na)\)的,\(a\)太大不好辦。
然後gjx大佬告訴我,這個dp式是乙個關於\(j\)的\(2n\)次多項式,然後給我證了一下,但還是不太懂:
首先知道\(dp[i][1] = \frac\),猜想這可能是乙個\(2n\)次的。
然後把轉移方程中的\(dp[i - 1][j]\)不斷展開,得到了\(dp[i][j] = \sum _ ^ dp[k][j] *(k + 1)\)。於是發現,這是乙個關於\(j\)的\(2n\)次多項式。
(感覺自己還是不太理解)
(這篇題解的證明好像也不錯, 應該是數學歸納法,我得學一下)
知道這是個多項式,就可以拉格朗日差值了。
注意dp的邊界取值,我這裡debug了好久。
#include#include#include#include#include#include#include#include#include#includeusing namespace std;
#define enter puts("")
#define space putchar(' ')
#define mem(a, x) memset(a, x, sizeof(a))
#define in inline
typedef long long ll;
typedef double db;
const int inf = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 505;
inline ll read()
inline void write(ll x)
int a, n, mod;
ll fac[maxn << 1], dp[maxn << 1][maxn];
in ll quickpow(ll a, ll b)
ll inv[maxn << 1], pre[maxn << 1], suf[maxn << 1];
in ll calc(int n)
return ret;
}int main()
if(a <= (n << 1)) write(dp[a][n] * fac[n] % mod), enter;
else write(calc(n << 1) * fac[n] % mod), enter;
return 0;
}
國家集訓隊 旅遊
題目背景 ray 樂忠於旅遊,這次他來到了 t 城。t 城是乙個水上城市,一共有 nn 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有 n 1n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心...
國家集訓隊 Tree I
題目 給你乙個無向帶權連通圖,每條邊是黑色或白色。讓你求一棵最小權的恰好有nee dneed need 條白色邊的生成樹。題目保證有解。思路 凸優化裸題,要注意的就是,優先選白色 優先選黑色也行 主要是同一斜率可能會切到很多點,那麼就要有乙個標準,要麼選最小點,要麼選最大。另外求出來的點不一定是ne...
國家集訓隊 旅遊
ray 樂忠於旅遊,這次他來到了 t 城。t 城是乙個水上城市,一共有 n 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有 n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有些橋狹...