• 【洛谷 1385】密令


    题目描述

    给定一小写字母串s,每次操作你可以选择一个p(1<=p<|s|)执行下述修改中的任意一个:

    1. 将s[p]改为其字典序+1的字母,将s[p+1]改为其字典序-1的字母

    或 2. 将s[p]改为其字典序-1的字母,将s[p+1]改为其字典序+1的字母

    在经过任意多次操作后,串s能变化成多少种字符串?

    修改过程中必须保证s是合法的小写字母串(即不能对字母‘a’进行字典

    序-1的操作),答案对1000000007(10^9 + 7)取模。

    输入格式

    【输入格式】

    第一行一个整数T,表示数据组数

    接下来T行,每行一个小写字母串s。

    输出格式

    【输出格式】

    输出T行,每行一个整数表示答案。

    输入输出样例

    输入 #1
    【样例输入】
    3
    aaaaaaaaa
    ya
    klmbfxzb
    
    输出 #1
    【样例输出】
    0
    24
    320092793
    
     
    

    说明/提示

    【数据范围】

    对于30%的数据,T=1;|s|<=10 对于60%的数据,T<=10;

    对于100%的数据,T<=10000;1<=|s|<=100

    题解:由于不断变换的过程中,字典总和是不变的(你加上一个又减去一个变个p啊)

                根据这个性质,推一下背包,就出来了惹。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    typedef long long ll;
    ll f[134][3028];
    int T,n;
    char s[333];
    void work(){              
        for(int i=0;i<26;i++) f[1][i]=1;
        for (int i=2;i<=100;i++)//一共有i个字符 
            for(int j=0;j<=2800;j++)//字典序总和为j  
                for(int k=0;k<26;k++) //由上一个字符通过balabla转移过来 
                    if (j-k>=0) f[i][j]=(f[i][j]+f[i-1][j-k])%mod;
    }
    int main(){
        freopen("1385.in","r",stdin);
        freopen("1385.out","w",stdout);
        work();
        scanf("%d
    ",&T);    
        while(T--){
            scanf("%s
    ",s+1);
            int n=strlen(s+1),m=0;
            for(int i=1;i<=n;i++) m+=(s[i]-'a'); 
            printf("%d
    ",(f[n][m]-1)%mod);
        }
        return 0;
    }
  • 相关阅读:
    Python中CreateCompatibleDC和CreateBitmap造成的内存泄漏
    POJ 2420 模拟退火
    LR(1)分析表-语法树-四元式
    C语言文法
    计蒜客 18018 热爱工作的蒜蒜 最短路+dp
    HDU 5988 最小费用流
    POJ 1808 平方剩余
    POJ 2115 单变元模线性方程
    计蒜客 17414 Exponial 指数降幂公式
    计蒜客 17412 Card Hand Sorting 最长公共子序列
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11857289.html
Copyright © 2020-2023  润新知