题意就是输入三个数字 n m k, 给n个士兵排队
每个士兵三种G,R,P可选,求至少有m个连续的G士兵和最多有k个连续的R士兵的排列总和
分析题意:在n个士兵中至少有m个连续的G士兵和最多有k个连续的R士兵的排列总和
就等于 (在n个士兵中最多有k个连续的R士兵和最多有n个连续的G士兵) - (在n个士兵中最多有k个连续的R士兵和最多有m-1个连续的G士兵)
#include<iostream> #include<cmath> #include<cstdio> #include<sstream> #include<cstdlib> #include<string> #include<string.h> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #include<bitset> #include<cmath> #define eps 1e-6 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll __int64 #define LL long long #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #define M 1000000007 using namespace std; #define Maxn 1100000 LL dp[Maxn][5]; //dp[i][0]表示第i个为G,至多有u个连续G,至多有v个连续R的个数 //dp[i][1]表示第i个为R,.... //dp[i][2]表示第i个为P,.... LL n,m,k,u,v; LL Cal() { dp[0][0]=1; //初始状态 dp[0][1]=0; dp[0][2]=0; for(int i=1;i<=n;i++) { LL sum=(dp[i-1][0]+dp[i-1][1]+dp[i-1][2])%M; dp[i][2]=sum; if(i<=u) dp[i][0]=sum; else if(i==u+1) dp[i][0]=(sum-1)%M; else dp[i][0]=(sum-dp[i-u-1][1]-dp[i-u-1][2])%M; if(i<=v) dp[i][1]=sum; else if(i==v+1) dp[i][1]=(sum-1)%M; else dp[i][1]=(sum-dp[i-v-1][0]-dp[i-v-1][2])%M; //printf("u:%lld v:%lld i:%d %lld %lld %lld ",u,v,i,dp[i][0],dp[i][1],dp[i][2]); //system("pause"); } return (dp[n][0]+dp[n][1]+dp[n][2])%M; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%lld%lld%lld",&n,&m,&k)) { LL ans; u=n,v=k; ans=Cal(); //printf(":%lld ",ans); //system("pause"); u=m-1,v=k; //printf(":%lld ",Cal()); //system("pause"); ans=((ans-Cal())%M+M)%M; printf("%lld ",ans); } return 0; }