description
input
僅含一行,兩個正整數 n, p。output
僅含一行,乙個非負整數,表示你所求的答案對p取餘 之後的結果。sample input
sample output4 7
hint3
對於 20%的資料,滿足 n≤10;為什麼這是組合數呢?對於 40%的資料,滿足 n≤18;
對於 70%的資料,滿足 n≤550;
對於 100%的資料,滿足 3≤n≤4200,p≤10910^9109
101810^1018,1<=q<=10510^5105
有兩種方法,都是n2,一種需要組合數,另一種不需要。
我因為算錯數了,推式子的時候排除了這兩種方法。。。最後才撿回來
solution 1
設dp[i][j][st]表示目前你構成的山長度為i,以相對高度為j的山結尾,末端下降和上揚的狀態分別以st的0,1表示。
想不出怎麼遞推?打表啊!
dp[1][1]太特殊會被算2遍,不考慮。
發現兩個表貌似只是上下倒置了,打出乙個就可以。以st=1的表為例。
找規律(嚶嚶嚶我找了3天呢):dp[i][j]=∑k=1->jdp[i-1][i-k]
式子的含義是什麼呢?假如我們想要長度為i,最後一座山在這i個高度的高度排名為第j。
我們把最後一座山拿走,那麼如果倒數第二座山的高度比最後一座高,那麼它的排名-1。否則不變。
因為趨勢需要上揚,dp[i][j][0]+=dp[i-1][k][1];k再考慮到倒置的問題就得到了那個式子。
1 #include2317位元組int mod,n,dp[2][4222
],ans;
3 inline int modd(int p)
4int
main()
solution 2
考慮假如你已經造出了兩座山,現在需要合併它們。
考慮到所有情況,將不同的數分給兩座山的情況用組合數計算。
這是可實現的,和排列計數類似,但是我沒有實現,就不多說了。
公式什麼的看**吧。
1 #include2來自奶牛mikufunint c[2][4202],dp[4202][2];3
intmain()13}
14 printf("
%d",(dp[n][0]+dp[n][1])%p);
15 }
題解 地精部落 DP
設 f i 表示強制第乙個是谷的合法方案數 轉移列舉乙個排列的最大值在 就把序列分成了互不相干的兩個部分,把其中 i 1 choose j 1 的數字分配給前面部分,剩下的給後面。轉移從所有可以轉移的偶數過來 winlere include include include includeusing ...
地精部落 題解
題目描述 輸入格式 僅含一行,兩個正整數 n,p。輸出格式 僅含一行,乙個非負整數,表示你所求的答案對p取餘 之後的結果。樣例樣例輸入 4 7樣例輸出 3資料範圍與提示 對於 20 的資料,滿足 n 10 對於 40 的資料,滿足 n 18 對於 70 的資料,滿足 n 550 對於 100 的資料...
BZOJ 地精部落
僅含一行,兩個正整數 n,p。僅含一行,乙個非負整數,表示你所求的答案對 p 取餘 之後的結果。input 4 7output 3對於 20 的資料,滿足 n 10 對於 40 的資料,滿足 n 18 對於 70 的資料,滿足 n 550 對於 100 的資料,滿足 3 n 4200,p 10 9 ...