码迷,mamicode.com
首页 > 其他好文 > 详细

fzu2204 dp

时间:2015-10-06 20:50:14      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:


2015-10-06 19:31:05


 

 

 

n个有标号的球围成一个圈。每个球有两种颜色可以选择黑或白染色。问有多少种方案使得没有出现连续白球7个或连续黑球7个。

每组包含n,表示球的个数。(1 <= n <= 100000)

dp[i][0][x] 表示在第i为填黑色且加上第i位连续的前面有x个黑色的球,dp[i][1][x]表示在第i为填白色且加上第i位连续的前面有x个白色的球

我们只算第一个球为白色,那么最后计算出的个数会等于第一个球去黑色的个数,这个很好理解,只要把他们的颜色相对应的反转一下就好了。然后剩下的好了,

最后的答案 是 dp[n][0-1][1-6] 再减去一些首位连接会超过7个的方案就好了,枚举前几位分别放什么相同的颜色,然后后面减去就好了

技术分享
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn=100005;
const int mod=2015;
int dp[maxn][2][7];
int solve(int n){
   int ans=0;
   for(int i=0;i<(1<<n); i++)
    {
        int hei=0,bai=0;
        int bo=1;
        for(int j=0; j<n; j++){
            hei=0;bai=0;
            for(int k=0; k<7;k++)
                if( ( 1<<((j+k)%n) ) & i )bai++;
                else hei++;
            if(hei>=7||bai>=7){
                bo=0;break;
            }
        }
        if(bo)ans++;
    }
    return ans%mod;
}
int solve2(int n)
{
    int ans=0;
    for(int i=6; i>=1; i--)
    {
        ans=(ans+dp[n][0][i]+dp[n][1][i])%mod;
    }
    ans=(ans*2)%mod;
    for(int i=1; i<7; i++)
        {
              for(int j=7-i; j<=6; j++)
              {
                  ans=(ans-(dp[n-i][0][j]+dp[n-i][0][j])%mod+mod)%mod;
              }
        }
    return ans;
}
int main()
{
    memset(dp,0,sizeof(dp));
    dp[1][1][1]=1;
    for(int i=2; i<=100000; i++)
        {
              for(int j=1;j<=6;j++)
                dp[i][0][1]=(dp[i-1][1][j]+dp[i][0][1])%mod;
              for(int k=2; k<=6; k++)
                dp[i][0][k]=dp[i-1][0][k-1];
              for(int j=1; j<=6;j++)
                dp[i][1][1]=(dp[i-1][0][j]+dp[i][1][1])%mod;
              for(int k=2; k<=6; k++)
                dp[i][1][k]=dp[i-1][1][k-1];
        }
    int n;
    int cas;
    scanf("%d",&cas);
    for(int cc=1; cc<=cas; cc++)
    {
            scanf("%d",&n);
            if(n<7)
            {
                printf("Case #%d: %d\n",cc,1<<n);
            }
            else if(n<=15){
            int ans=solve(n);
            printf("Case #%d: %d\n",cc,ans);
            }else{int d=solve2(n);
            printf("Case #%d: %d\n",cc,d);
            }
    }
    return 0;
}
View Code

 

fzu2204 dp

标签:

原文地址:http://www.cnblogs.com/Opaser/p/4857586.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!