zoukankan      html  css  js  c++  java
  • CF156C Cipher

    洛谷题目 CF原题

    见过计数DP,也见过字符串的计数DP,但是这样的是第一次见。

    Solution

    看到要求方案数,那么一定是计数DP了。这字符串你还想用组合数?

    但是设计什么状态能够得到最后答案呢?限制有点多诶^_~

    发现题面中的两种运算都是对称的,一个往字母表后,另一个必定往前。

    等等,字母表?ASCII码?

    哦~一个ASCII码增加 (x) ,另一个减少 (x) 吖(o゚v゚)ノ(注意不是一个位置只能运算一次)。也就是说整个字符串的ASCII码之和是不变的。

    那么可以设 (dp_{i,j}) 表示长度为 (i) ,ASCII码之和为 (j) 的方案数

    可得一个显然的转移方程:

    [dp_{i,j}=sum_{k=min(1,j-26)}^{26}dp_{i-1,j-k} ]

    而且,最最最重要的是我们得到的 (dp) 数组是可以预处理出来的,不用每次查询现转移。

    小细节:因为题目要求的是一共有多少种与它意思一致的单词,所以要减去它本身,即 (-1)

    Code

    #include<bits/stdc++.h>
    
    using namespace std;
    const int mod=1e9+7;
    int dp[110][3010],t,sum;
    string s;
    
    int main(){
        scanf("%d",&t);
        for(int i=1;i<=26;i++) dp[1][i]=1;
        for(int i=2;i<=101;i++)
            for(int j=i;j<=26*i;j++)
                for(int k=max(1,j-26);k<=j-1;k++)
                    dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
        while(t--){
            cin>>s;
            sum=0;
            for(int i=0;i<s.size();i++) sum+=s[i]-'a'+1;
            printf("%d
    ",(dp[s.size()][sum]-1)%mod);
        }
        return 0;
    }
    
  • 相关阅读:
    数据库语句
    Java类和数据结构中常用的方法
    java知识点
    JVM相关知识
    Java实现三种常用的查找算法(顺序查查找,折半查找,二叉排序树查找)
    SharedPreference作用及数据操作模式
    Java实现7种常见的排序算法
    钱多多软件制作03
    钱多多软件制作02
    钱多多软件制作01
  • 原文地址:https://www.cnblogs.com/jasony/p/13872567.html
Copyright © 2011-2022 走看看