其實只是因為要給同學出題找的這道題, 不過在網上看到的一些題解似乎對乙個細節並沒有寫得清楚,在此寫個題解
沒想到之前太早發,又碰上愛學習的神犇wx同學…
有grp三個軍種,g最多連續m個,r最少連續k個,求安排n個的方案數
有多個測試用例(反正跑得過)。對於每種情況,存在包含3個整數n(0
每種情況下一行,應輸出mod 1000000007後的結果
3 2 2
將駐軍,偵察機關和軍警視為g,r和p.
合理安排有:ggg,ggr,ggp,rgg,pgg。
因要判斷不同軍種的連續性問題,需要開兩維,一維表示當前是第i個,一維表示當前軍種為j
首先為了方便用同乙個表示方法表示,當然最好是將最多最少連續同一:將最多連續轉化為最少連續或將最少連續轉化為最多連續
上面設的部分中還沒說表示什麼,比較可以發現將最少連續轉化為最多連續是最方便的
而如何將最少連續轉化為最多連續呢?
類似組合數學的,可以用最多連續n個減去最多連續m-1個表示
用u,v表示每次計算時g最多連續u個,r最多連續v個
答案即為兩次遞推答案相減,v不變,u一次為n,一次為m-1
無需考慮前面情況,全部加起來即可
i <=u時
不可能多過連續要求,全部加起來即可
i == u+1時
有一種情況正好超過連續要求,全部加起來減去1即可
i>u+1時
我就是說這個細節應該用更好的方式理解
當然會有多種情況超過連續要求
這個時候網上的題解是類似於
//減去i-1~i-u-1全是g的情況其實我覺得可以跟之前最少連續轉最多連續一樣的方法理解
為了不出現超過連續要求的情況,
逆向思考這種情況即為 至少有i-u個其他兵種在前,於是
每乙個其他兵種這樣的情況自然為(f
i−1,
x−fi
−u−1
,x) ,有兩種其他兵種,與當前兵種正常加起來即可
類似可推出
#include
#include
const int
mod = 1000000007, maxn = 1e6 + 100;
typedef long
long ll;
ll dp[maxn][3]; //0 g, 1 r, 2 p
int n, m, k;
ll work(int u, int v)
return ((dp[n][0] + dp[n][1]) % mod + dp[n][2]) % mod;
}int main ()
return
0;}
zoj 3747 排列組合dp
題意 現在要挑選n個士兵成為乙個排列,從三個不同的軍團之中,第乙個軍團最少u個人連續站在一起,第二個軍團最多有v個士兵站在一起,問有多少種不同的挑選方式。思路 對於最多和最少問問題盡量轉化為最多的問題,比如第乙個軍團的限制條件,那麼在求的時候轉化為最多有i個人。排列組合計數問題很容易從前乙個狀態推到...
簡單dp之遞推 2 ZOJ 3747
zoj 3747 給n個士兵排隊,每個士兵有三種型別g r p可選,求至少有m個連續g士兵,最多有k個連續r士兵的排列的種數。input there are multiple test cases.for each case,there is a line containing 3 integers...
統計數對 題解
a1350.數對統計 羅劍橋 時間限制 1.0s 記憶體限制 256.0mb 試題 ioi2012中國國家隊訓練 問題描述 你得到了乙個由 n 個非負整數構成的序列 a。你需要回答關於這個序列的 q 次詢問。每次詢問將提供三個整數引數 v,a,b。你需要統計滿足以下三個條件的整數 數對 i,j 的數...