您的位置:首页 > 其它

JZOJ1292. 公牛和母牛

2018-02-08 11:31 197 查看

Description

  FJ想N头牛(公牛或母牛)排成一排接受胡总的检阅,经研究发现公牛特别好斗,如果两头公牛离得太近就会发生冲突,通过观察两头公牛之间至少要有K(0<=K<=N)头母牛才能避免冲突。

  FJ想请你帮忙计算一共有多少种放置方法,注意所有的公牛被认为是一样的,母牛也是,所以两种放置方法被认为不同当且仅当某些位置牛的种类不同。

Input

  第一行:两个空格隔开的整数N(N<=100000)和K。

Output

  输出一个整数表示方法总数,答案可能很大,所以只需输出mod 5,000,011的值即可。

Sample Input

4 2

Sample Output

6

Hint

以下为6种放置方法,‘B’表示公牛,‘C’表示母牛

CCCC

BCCC

CBCC

CCBC

CCCB

BCCB

题解

很自然地想到一个状态:fi表示i这个位置放一头公牛的方案数,

它可以从前面距离超过k的状态转移过来。

随便维护一下前缀和,直接转移。

时间复杂度O(n)。

code

#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 100003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
#define mo 5000011
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}

int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}

int n,k,s,a
,ans;

int _a(int x){return x>mo?x-mo:x;}

int main()
{
read(n);read(k);
for(int i=0;i<=k;i++)
a[i]=1;

s=0;ans=k+1;
for(int i=k+1;i<=n;i++)
{
s=_a(s+a[i-k-1]);
a[i]=s;
ans=_a(ans+a[i]);
}

write(ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: