題目連結:http://www.lydsy.com/JudgeOnline/problem.php?id=3398
題意:
約翰要帶N(1≤N≤100000)只牛去參加集會裡的展示活動,這些牛可以是牡牛,也可以是牝牛。
牛們要站成一排。但是牡牛是好鬥的,為了避免牡牛鬧出亂子,約翰決定任意兩隻牡牛之間至少要有K(0≤K<N)只牝牛。
請計算一共有多少種排隊的方法。所有牡牛可以看成是相同的,所有牝牛也一樣。答案對5000011取模。
題解:
表示狀態:
dp[i] = num of ways
表示考慮到位置i,並且在這裡放了牡牛的方案數。
找出答案:
ans = ∑(dp[i]) + 1
因為不放牡牛也算一種方案,所以最後+1。
如何轉移:
dp[i] = ∑ dp[0 to i-k-1] + 1
上一次放牡牛的位置至少在i前面k+1個牛的位置。
或者這是第一次放牡牛,所以+1。
優化:
字首和優化。
AC Code:
1 // state expression: 2 // dp[i] = num of ways 3 // i: last pos of cow2 4 // 5 // find the answer: 6 // sigma dp[i] + 1 7 // 8 // transferring: 9 // dp[i] = sigma dp[0 to i-k-1] + 1 10 // 11 // boundary: 12 // set dp = 0 13 #include <iostream> 14 #include <stdio.h> 15 #include <string.h> 16 #define MAX_N 100005 17 #define MOD 5000011 18 19 using namespace std; 20 21 int n,k; 22 int ans; 23 int dp; 24 int sum[MAX_N]; 25 26 void read() 27 { 28 cin>>n>>k; 29 } 30 31 void solve() 32 { 33 sum[0]=0; 34 ans=1; 35 for(int i=1;i<=n;i++) 36 { 37 dp=1; 38 if(i-k-1>=0) dp=(dp+sum[i-k-1])%MOD; 39 sum[i]=(sum[i-1]+dp)%MOD; 40 ans=(ans+dp)%MOD; 41 } 42 } 43 44 void print() 45 { 46 cout<<ans<<endl; 47 } 48 49 int main() 50 { 51 read(); 52 solve(); 53 print(); 54 }