BZOJ 2272 [Usaco2011 Feb]Cowlphabet

BZOJ_2272

    可以用f[i][j][k]表示递推到第i个字符时,大写字符已经有了j个,且最后一个字符是k,这样总状态一共约有500*250*52,总的状态转移次数约有500*250*200,是可以承受的。

#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<vector>
#define MOD 97654321
int N, U, L, P, f[2][260][128];
std::vector<int> g[128];
void init()
{
    N = U + L;
    char b[5];
    for(int i = 0; i < 128; i ++) g[i].clear();
    for(int i = 0; i < P; i ++)
    {
        scanf("%s", b);
        g[b[1]].push_back(b[0]);
    }
}
void solve()
{
    int cur = 0, ans = 0;
    memset(f[0], 0, sizeof(f[0]));
    for(int i = 'a'; i <= 'z'; i ++) f[0][0][i] = 1;
    for(int i = 'A'; i <= 'Z'; i ++) f[0][1][i] = 1;
    for(int i = 2; i <= N; i ++)
    {
        cur ^= 1;
        for(int j = 0; j <= U; j ++)
        {
            for(int k = 'A'; k <= 'Z'; k ++)
            {
                f[cur][j][k] = 0;
                if(j > 0)
                    for(int t = 0; t < g[k].size(); t ++)
                        f[cur][j][k] = (f[cur][j][k] + f[cur ^ 1][j - 1][g[k][t]]) % MOD;
            }
            for(int k = 'a'; k <= 'z'; k ++)
            {
                f[cur][j][k] = 0;
                for(int t = 0; t < g[k].size(); t ++)
                    f[cur][j][k] = (f[cur][j][k] + f[cur ^ 1][j][g[k][t]]) % MOD;
            }
        }
    }
    for(int i = 'a'; i <= 'z'; i ++) ans = (ans + f[cur][U][i]) % MOD;
    for(int i = 'A'; i <= 'Z'; i ++) ans = (ans + f[cur][U][i]) % MOD;
    printf("%d\n", ans);
}
int main()
{
    while(scanf("%d%d%d", &U, &L, &P) == 3)
    {
        init();
        solve();
    }
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值