簡單dp之遞推 2 ZOJ 3747

2021-08-07 14:50:29 字數 1712 閱讀 2968

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 n (0 < n < 1000000), m (0 < m < 10000) and k (0 < k < 10000), separated by spaces.

output

one line for each case, you should output the number of ways mod 1000000007.

sample input

3 2 2

sample output5

hint

denote the garrison, the recon corp and the military police as g, r and p. reasonable arrangements are: ggg, ggr, ggp, rgg, pgg.

由於又是至多又是至少沒辦法處理,所以統一轉換成至多,對於事件a=,事件b=,那麼a-b=。統一之後,

設dp[i][j]表示前i個士兵,當第i個士兵是第j種兵(假設g:0,r:1,p:2)時,g至多連續u個、r至多連續v個的排列個數。

令sum=dp[i-1][0]+dp[i-1][1]+dp[i-1][2];對於不作要求的p士兵,它可以由第i-1階段的三種士兵任意轉移:dp[i][2]=sum。

另:

對於g種兵

假設 i<=u 這時第i個位置可以隨意放入grp任意一種,即dp[i][0]=sum;

假設i==u+1時這時要排除1~u 全為g的情況 所以此時的dp[i][0]=sum-1;

假設i>u+1 時這時要排除i-u~i-1全為g的情況 這種狀態即為i-u~i-1全為g時i-u-1為p或r的情況,即dp[i][0]=sum-dp[i-u-1][1]-dp[i-u-1][2];

對於r種兵,則與上述g種兵類似。

初始化時,對於第0個位置,整體為1即可,也可理解為對第0個位置放p,並沒有什麼影響。 dp[0][2]=1,dp[0][0]=dp[0][1]=0; (其實只需要dp[0][2]+dp[0][1]+dp[0][0]=0;即可)

這樣,我們令u分別等於n和m-1,v等於k,進行兩次遞推,得到的結果相減即是答案。

#include 

#include

using namespace std;

#define ll long long

#define mod 1000000007

ll dp[1000009][3]; //g:0 r:1 p:2

ll n,m,k;

ll fun(ll u,ll v)

return (dp[n][0]+dp[n][1]+dp[n][2])%mod;

}int main()

return

0;}

UVa 926 簡單dp,遞推

uva 926 題意 給定n n的街道圖和起始點,有些街道不能走,問從起點到終點有多少種走法。很基礎的dp 遞推,但是有兩個地方需要注意,在標記當前點某個方向不能走時,也要同時標記對應方向上的對應點。另一點就是要開long long存。要是不考慮障礙的話,按組合數算從 1,1 走到 n,n 需要2 ...

UVa 825 簡單dp,遞推

uva 825 題意 給定乙個網格圖 街道圖 其中有一些交叉路口點不能走。問從西北角走到東南角最短走法有多少種。好像沒看到給資料範圍。簡單的遞推吧,當然也就是最簡單的動歸了。顯然最短路長度就是row col。求種數就從開始往後推。由於第一行第一列也有可能是障礙點,所以初始化時要注意這一點,或者乾脆就...

阿牛的EOF牛肉串 簡單遞推型dp

hdu2047傳送門 今年的acm暑期集訓隊一共有18人,分為6支隊伍。其中有乙個叫做eof的隊伍,由04級的阿牛 xc以及05級的coy組成。在共同的集訓生活中,大家建立了深厚的友誼,阿牛準備做點什麼來紀念這段激情燃燒的歲月,想了一想,阿牛從家裡拿來了一塊上等的牛肉乾,準備在上面刻下乙個長度為n的...