【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)

ACM字符串
1.长度不能超过n
2.字符串中仅包含大写字母
3.生成的字符串必须包含字符串“ACM”,ACM字符串要求连在一块!

ok,是不是很简单?现在告诉你n的值,你来告诉我这样的字符串有多少个

输入

输入一个正整数T,代表有T组数据
接下来T行,每行一个正整数n,n<=10。 

输出

输出符合条件的字符串的数目

样例输入

1
3

样例输出

1

做题过程:

  1. 熬了三四个小时,WA了无数次!最终推出了组合数的公式!
  2. 首先暴力打表,嘿嘿!这样极大地压缩计算时间!
  3. 打表如下:

    一:生成连续的7位绝对不含ACM的数据的个数!

    ll Els[10];//生成7位绝对不含ACM的数据
    int a[10];
    
    void dfs(int now,int len)
    {
        if(now>len)
        {
            Els[len]++;
            return ;
        }
        for( int i=1; i<=26; i++)
        {
            a[now]=i;
            if(now>=3&&a[now]==3&&a[now-1]==2&&a[now-2]==1)
                continue;
            dfs(now+1,len);
        }
    }
    int main()
    {
    
        for(int i=1; i<=3; i++)
        {
            dfs(1,i);
            printf("i=%d, %lld\n",i,Els[i]);
        }
    
        cout<<"生成连续的7位绝对不含ACM的数据"<<endl;
        for(int i=1; i<=3; i++)
        {
            printf("i=%d, %lld\n",i,Els[i]);
        }
    
        return 0;
    }
  4. 二:开始进行组合数学处理,并且处理误差!

  5. 误差是怎么回事呢?举个栗子当“n=6时,形如当只含有一个ACM时—— “ACM_ _ _”这种样子C(4,1)种组合数(把ACM捆绑成一块!),然后需要C(4,1) 乘于其余三个空位上的数字组合,这三种数字“因为不能再含有ACM”直接调用上面求出的Els[3], 但是这里存在了误差!
  6. 仔细考虑一下,当出现“_ACM_ _”的组合的这种情况时,其实有Els[1]*Els[2] 种!也就是说中间的“ACM”隔开了两边,我上面求的那么“Els”的真实意思是“生成连续的7位绝对不含ACM的数据个数”!Els[1]*Els[2] -Els[3] = 1 ,这里的误差就是1!以此类推!
  7. 同理,其他的情况也是如此!多的位数可以跑循环进行枚举!手写就有点麻烦了!
#define ll long long
ll F[12]; //n的阶乘
//ll f[12];
                ///chart表示连续的绝对不含ACM连续的字符串个数,就是上面求出的"Els 数组"
ll chart[12]={1,  26,676,17575,  456924,11879348,308845473,  8029525374};
ll mistake[12];    ///存储每个长度n的误差!
ll Cul(int m,int k)  //计算C(m,k)的组合数
{
    return F[m]/(F[k]*F[m-k] );
}
ll ans[12]={0,0,0,1};
void init(){
    F[0]=1;
    for(int i=1;i<=10;i++)  //n的阶乘!
        F[i]=F[i-1]*i;
    memset(mistake,0,sizeof(mistake));
    mistake[6]+= chart[1]*chart[2]*2- 2*chart[3];
    mistake[7]+= chart[1]*chart[3]*2+chart[2]*chart[2]- 3*chart[4];
    mistake[8]+= chart[1]*chart[4]*2+chart[2]*chart[3]*2- 4*chart[5];
    mistake[9]+= chart[1]*chart[5]*2+chart[2]*chart[4]*2+chart[3]*chart[3] - 5*chart[6];
    mistake[9]+= chart[1]*chart[2]*6 +chart[1]*chart[1]*chart[1] - chart[3]*7;

    for(int i=1;i<=7;i++)  ///__A_____
        mistake[10]+=chart[i]*chart[7-i]-chart[7];
    for(int j=0;j<=4;j++){
        for(int i=0;i+j<=4;i++)  ///_A__A__(空出j个位置和i个位置和4-i-j个位置!!)
            mistake[10]+=chart[j]*chart[i]*chart[4-i-j]-chart[4];
    }

}
int main(){

    init();

    for(int j=4;j<=10;j++)
    {
       int n=j;
        int num=n/3;
         ans[j]=ans[j-1];
        for(int i=1;i<=num;i++){  //单个的,结果需要累加!!
            ans[j]+=Cul(i+n-i*3,i)*chart[n-i*3] ;
        }
      //   printf("j=%d, %lld\n",j,ans[j]);
        ans[j]+= mistake[j];
     //   printf("+mis::  j=%d, %lld\n",j,ans[j]);
    }

    int T;
    scanf("%d",&T);

    while(T--){
        int n;
        cin>>n;

        printf("%lld\n",ans[n]);
    }

    return 0;
}

官方题解是数位DP来写,数位DP其实就是记忆化搜索+深搜!建议学学!

原文地址:https://www.cnblogs.com/zhazhaacmer/p/9690913.html

时间: 2024-11-10 11:14:01

【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)的相关文章

2020-3-14 acm训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019 解题报告+补题报告

2020-3-15比赛解题报告+2020-3-8—2020-3-15的补题报告 2020-3-15比赛题解 训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019  A建筑(模拟) 耗时:3ms 244KB 建筑 你哥哥在最近的建筑问题突破大会上获得了一个奖项 并获得了千载难逢的重新设计城市中心的机会 他最喜欢的城市奈梅根.由于城市布局中最引人注目的部分是天际线, 你的兄弟已经开始为他想要北方和东方的天际线画一些想法

4.7-4.9补题+水题+高维前缀和

题目链接:51nod 1718 Cos的多项式  [数学] 题解: 2cosx=2cosx 2cos2x=(2cosx)^2-2 2cos3x=(2cosx)^3-3*(2cosx) 数归证明2cos(nx)能表示成关于2cosx的多项式,设为f(n) f(1)=x,f(2)=x^2-2(其中的x就是2cosx) 假设n=1~k时均成立(k>=3) 当n=k+1时 由cos((k+1)x)=cos(kx)cos(x)-sin(kx)sin(x) cos((k-1)x)=cos(kx)cos(x)

【补题】组队训练第一场

本来想一次补完的(正常应该补两次的)但是晚上玩dota2和rpg去了然后--又堕落了啊. 好吧进入正题,题目按照从易到难的顺序(个人感觉)其他题目现在对我来说太难了,以后再补. A题 ZOJ 3878 水题,可以用map一个一个对应,比较麻烦就用了两个字符数组,要注意\和"要转义. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5

4.30-5.1cf补题

//yy:拒绝转载!!! 悄悄告诉你,做题累了,去打两把斗地主就能恢复了喔~~~ //yy:可是我不会斗地主吖("'▽'") ~~~那就听两遍小苹果嘛~~~ 五一假期除了花时间建模,就抽空把最近没做的CF题补了点..毕竟明天开始又要继续上好多课呐...Yes, I can!(? •_•)?……(I can Huá shuǐ~~) codeforces 803 A. Maximal Binary Matrix   [简单构造] 题意:n行和n列填充零矩阵. 您要将k个1放在其中,使得得到

hdu5017:补题系列之西安网络赛1011

补题系列之西安网络赛1011 题目大意:给定一个椭球: 求它到原点的最短距离. 思路: 对于一个椭球的标准方程 x^2/a^2 + y^2/b^2 +z^2/c^2=1 来说,它到原点的最短距离即为min(a,b,c) 所以我们需要把原方程化为标准型. 这时候线代就排上用场了,注意到原方程是一个二次型. 化为标准型 1/(k1)*x^2+1/(k2)*y^2+1/(k3)*z^2=1 后  min(k1,k2,k3)即为答案 而这里的1/k1,1/k2,1/k3 就是二次型矩阵的特征值 如何求特

20190303集训队选拔赛1补题报告

今天嘛,打得很糟糕,糟糕到什么程度呢,rank40 一共才55个人,我写了2题,总共尝试了5题,总共8题 写了3题及以上的有27个,剩下的都是2道和1道 小西瓜啊!!! 外因就不找了(其实也没有) 但是我知道有个原因非常重要:刷题量太少了 其他的不说了,再接再厉吧,刚才已经消沉了很久了,也放空了一会,所以开始补题吧 对了,集训队讲座补选上了(因为有的同学觉得太难退课了,感谢颜学长的劝退讲座,让我有机会一边修学分一边被虐) 这也意味着我要有一篇总结报告和三篇解题报告 解题报告要正儿八经地写 不能像

Codeforces Round #634 (Div. 3) 补题

A. Candies and Two Sisters 签到题,直接输出即可 代码 #include<bits/stdc++.h> #define INF 0x3f3f3f3f typedef long long ll; using namespace std; inline void read(int &p) { p=0;int flag=1;char c=getchar(); while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();} w

[2015hdu多校联赛补题]hdu5371 Hotaru&#39;s problem

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5371 题意:把一个数字串A翻过来(abc翻过来为cba)的操作为-A,我们称A-AA这样的串为N-sequence,现在给你一个数字串,问你这个串中最长的N-sequence子串长度 解:可以想到A-A是一个回文串,-AA也是一个回文串,那么首先Manacher跑一遍求出所有回文子串 可以想到任意两个互相覆盖的回文子串都可以表示成N-sequence 然后有三种搞法: 1.时间复杂度O(N*logN

补题 留空

这两道题虽然不是很难,但是目前还不会,在这留个地,省赛之后多刷点这种类型的题,再补上. 1. http://acm.hdu.edu.cn/showproblem.php?pid=3306 矩阵快速幂的题,相加平方和. 2.http://acm.hdu.edu.cn/showproblem.php?pid=3308 线段树 补题 留空,码迷,mamicode.com