1. 程式人生 > >ZOJ - 3747 Attack on Titans

ZOJ - 3747 Attack on Titans

1.0 efi time ack 題意 amp can sta ()

題意就是輸入三個數字 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\n",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\n",ans); //system("pause"); u=m-1,v=k; //printf(":%lld\n",Cal()); //system("pause"); ans=((ans-Cal())%M+M)%M; printf("%lld\n",ans); } return 0; }

ZOJ - 3747 Attack on Titans