2017.3.23 模拟赛

t1
Problem A: 字符串统计
文件名:notes.cpp
读入文件:notes.in
输出文件:notes.out
单点时限:1000ms
内存限制:256MB
描述
定义一种字符串,由 3 种大写字母 O,L,A 组成。
一个合法的字符串需要满足:A 至多出现一次,且不得出现 3 个连续的 L。
例如:OOLLOLLOALL 就是合法的,而 OLLLAOO 就是不合法的,因为连续出现了三个 L。
现在输入字符串的长度 n,求所有长度为 n 的串中,有多少是合法的。 输入
一个整数 n。 输出
长度为 n 的串中,合法串的总数。
由于结果可能很大,你只需输出结果模10 7
9  的余数。 样例输入
3
样例输出
19
样例解释
长度为 3 的合法的字符串有 19 种。 子任务
对于 20%的数据,n 15;
对于 50%的数据,n  20 ;
对于 80%的数据, 5 n 10 ;
对于 100%的数据, 6 n  510 。
5秒出答案
不过好像做麻烦了

f[i][0][0]+=f[i1][0][0]+f[i1][0][1]+f[i1][0][2];f[i][1][0]+=f[i1][1][0]+f[i1][1][2];f[i][0][1]+=f[i1][0][0];f[i][0][2]+=f[i1][0][1];f[i][1][1]+=f[i1][1][0];f[i][1][2]+=f[i1][1][1];

f[i][j][k]ijakl

/*
    Name: t1
    Copyright: 
    Author: 
    Date: 23-03-17 19:45
    Description: 
*/

#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define maxn 5000500
#define ll unsigned int
inline ll read()
{
    ll rt=0,ff=1;char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            ff=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        rt=rt*10+ch-'0';
        ch=getchar();
    }
    return rt*ff;
}
/*
1 o
2 a
3 l
*/
ll f[maxn][2][4];
int n;
int main()
{
    freopen("notes.in","r",stdin);
    freopen("notes.out","w",stdout);
    n=read();
    f[1][0][0]=1;
    f[1][1][0]=1;
    f[1][0][1]=1;
    for(int i=2;i<=n;i++)
    {
        /* for o*/
        f[i][0][0]=(
            f[i][0][0]+
            f[i-1][0][0]+
            f[i-1][0][1]+
            f[i-1][0][2]
        )%mod;
        f[i][1][0]=(
            f[i][1][0]+
            f[i-1][1][0]+
            f[i-1][1][1]+
            f[i-1][1][2]
        )%mod;
        /* for o*/
        /* for a*/
        f[i][1][0]=(
            f[i][1][0]+
            f[i-1][0][0]+
            f[i-1][0][1]+
            f[i-1][0][2]
        )%mod;
        /*for a*/
        /*for l*/
        f[i][0][1]=(
            f[i][0][1]+
            f[i-1][0][0]
        )%mod;
        f[i][0][2]=(
            f[i][0][2]+
            f[i-1][0][1]
        )%mod;
        f[i][1][1]=(
            f[i][1][1]+
            f[i-1][1][0]
        )%mod;
        f[i][1][2]=(
            f[i][1][2]+
            f[i-1][1][1]
        )%mod;
        /*for l*/
    }   
    ll ans=0;
    for(int i=0;i<=1;i++)
        for(int j=0;j<=2;j++)
            ans=(ans+f[n][i][j])%mod;
    cout<<ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值