fzu2204 7
Problem Description
n个有标号的球围成一个圈。每个球有两种颜色可以选择黑或白染色。问有多少种方案使得没有出现连续白球7个或连续黑球7个。
Input
第一行有多组数据。第一行T表示组数。(T <= 20)
每组包含n,表示球的个数。(1 <= n <= 100000)
Output
每组先输出 "Case #x: " (其中x为当前组数) 该行接下来输出方案数。方案数mod 2015。
Sample Input
271
Sample Output
Case #1: 126Case #2: 2
Source
FOJ有奖月赛-2015年10月这道题可以用dp做,用dp[i][j][k]表示前i个球中,末尾连续j个白球,连续k个黑球的方案数,那么跟fzu2200那题一样,因为是环,所以我们可以枚举开始的状态(即开始有多少个黑球连续,这里我们只要考虑有几个黑球就行,因为是对称的,所以最后答案只要乘2就行了),然后每一步枚举取白球还是黑球,状态转移一下就行了。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 0x7fffffff
#define maxn 100050
#define MOD 2015
ll dp[maxn][7][7],rear[maxn];
void init()
{
int i,j,k,ii,jj;
memset(rear,0,sizeof(rear));
for(k=1;k<=6;k++){
memset(dp,0,sizeof(dp));
dp[k+1][1][0]=1;
for(i=k+1;i<=100020;i++){
//放黑球
for(ii=1;ii<=6;ii++){
dp[i][0][1]=(dp[i][0][1]+dp[i-1][ii][0])%MOD;
}
for(ii=1;ii<=5;ii++){
dp[i][0][ii+1]=(dp[i][0][ii+1]+dp[i-1][0][ii])%MOD;
}
//放白球
for(ii=1;ii<=6;ii++){
dp[i][1][0]=(dp[i][1][0]+dp[i-1][0][ii])%MOD;
}
for(ii=1;ii<=5;ii++){
dp[i][ii+1][0]=(dp[i][ii+1][0]+dp[i-1][ii][0])%MOD;
}
//加入到答案中
for(ii=1;ii<=6;ii++){
rear[i]=(rear[i]+dp[i][ii][0])%MOD;
}
for(ii=1;ii+k<7;ii++){
rear[i]=(rear[i]+dp[i][0][ii])%MOD;
}
}
}
}
int main()
{
int n,m,i,j,T,cas=0;
init();
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
cas++;
printf("Case #%d: ",cas);
if(n<=6){
int ans=1;
for(i=1;i<=n;i++)ans*=2;
printf("%d\n",ans);
continue;
}
printf("%I64d\n",rear[n]*2%MOD);
}
return 0;
}