串的计数--动态规划和高精度

来源:互联网 发布:游族网络 大皇帝ol 编辑:程序博客网 时间:2024/05/20 16:11

http://www.rqnoj.cn/Problem_38.html

题目:串的记数

问题编号:38

题目描述

一个长度为3N字符串满足:由N个A,N个B,N个C组成,对于它的任意前缀,满足A的个数>=B的个数>=C的个数。求满足这样条件的字符串的个数。
数据范围:
10%的数据满足0<=n<=5
100%的数据满足0<=n<=60

输入格式

输入文件只有一行,为1个整数N(0<=n<=60)。

输出格式

所求的答案

样例输入

4

样例输出

462


一、思路
每个字串以A或B或C结束 那么定义f[a][b][c],来表示当有a个A,b个B,c个C时的满足题意的字符串个数
f[a][b][c] = f[a-1][b][c]+f[a][b-1][c]+f[a][b][c-1] 即以A结束有f[a-1][b][c]个 B结束有f[a][b-1][c] C结束有f[a][b][c-1]个 三者的总和
初始条件为f[0][0][0] = 1 且 a>=b>=c 否则为0

因为数据量70多位 所以用到了高精度加法
f[a][b][c][20] 来存储,其中第四维来表示个数,用20个整型数来表示 8*20= 160 位数 足够了对本题


1、读入n
2、三重循环,动态规划,高精度加法求和
3、输出结果
1)找到最高位
2)补0输出非最高位
二、代码如下
#include <iostream.h>#include <fstream.h>#define NUM 10000000int f[61][61][61][20];int main(){int n;int a, b, c, p;int i, j;//读入ncin>>n;f[0][0][0][0] = 1;for (a=0; a<=n; a++){for (b=0; b<=a; b++){for (c=0; c<=b; c++){//高精度 1 000 000for (p=0; p<20; p++){f[a][b][c][p] += a>0?f[a-1][b][c][p]:0;//防止越界f[a][b][c][p] += b>0?f[a][b-1][c][p]:0;f[a][b][c][p] += c>0?f[a][b][c-1][p]:0;if (!f[a][b][c][p]){break;}if (f[a][b][c][p]>=NUM){f[a][b][c][p+1] += f[a][b][c][p]/NUM;f[a][b][c][p] %= NUM;}}}}} //输出,找最高位置p=19;while (!f[n][n][n][p]) {p--;}p = p<0?0:p;//输出最高位cout<<f[n][n][n][p];//补0输出for (p=p-1; p>=0; p--){//判断位数int bit = 10;for (i=1; i<=7; i++){if (f[n][n][n][p]/bit==0){break;}bit *= 10;}//输出0for (j=1; j<=7-i; j++){cout<<0;}cout<<f[n][n][n][p];}return 0;}



原创粉丝点击