ACWing 1307. 牡牛和牝牛 (组合数、DP、前缀和)

1307. 牡牛和牝牛

思路一

  • f [ i ] f[i] f[i]表示有 i i i个奶牛且最后一个牛必须为公牛的方案数。
  • f [ i ] = ∑ 0 i − k − 1 f [ i ] f[i] =\sum_{0}^{i-k-1} f[i] f[i]=0ik1f[i] ( s [ i − k , i − 1 ] ) (s[i-k,i-1]) (s[ik,i1])只能放母牛。
  • 最终答案: ∑ 0 n f [ i ] \sum_{0}^{n}f[i] 0nf[i],分类做事情,加法原理。
#include 
using namespace std;

const int mod = 5000011,size = 1e5+10;
int n,k,f[size] = {
     1},s[size] = {
     1};

int main(){
     
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
     
        f[i] = i-k-1>=0?s[i-k-1]:f[0];
        s[i] = (s[i-1]+f[i])%mod;
    }
    printf("%d\n",s[n]);
    return 0;
}

思路二

  • 直接用 f [ i ] f[i] f[i]表示有 i i i头牛的方案数
    • 如果第 i i i头牛是母牛,那么前 i − 1 i-1 i1头按照题目要求随便放置即可。
    • 如果第 i i i头牛是公牛, s [ i − k ] s[i-k] s[ik]~ s [ i − 1 ] s[i-1] s[i1]都不可以是公牛,只能都是母牛。
      所以此时 i − k − 1 i-k-1 ik1头牛按照题目要求任意放置。
      f [ i ] = f [ i − 1 ] + f [ i − k − 1 ] f[i]=f[i-1]+f[i-k-1] f[i]=f[i1]+f[ik1]
  • 答案就是 f [ n ] f[n] f[n]
#include 
using namespace std;

const int mod = 5000011,size = 1e5+10;
int n,k,f[size] = {
     1};

int main(){
     
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
     
        f[i] = f[i-1];
        if(i-k-1>=0) f[i] = (f[i]+f[i-k-1])%mod;
        else f[i] = (f[i]+1)%mod;
    }
    printf("%d\n",f[n]);
    return 0;
}

你可能感兴趣的:(#,组合计数,#,计数类DP)