刷题总结——regular words(hdu1502 dp+高精度加法+压位)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题总结——regular words(hdu1502 dp+高精度加法+压位)相关的知识,希望对你有一定的参考价值。

题目:

Problem Description

Consider words of length 3n over alphabet {A, B, C} . Denote the number of occurences of A in a word a as A(a) , analogously let the number of occurences of B be denoted as B(a), and the number of occurenced of C as C(a) . 

Let us call the word w regular if the following conditions are satisfied: 

A(w)=B(w)=C(w) ; 
if c is a prefix of w , then A(c)>= B(c) >= C(c) . 
For example, if n = 2 there are 5 regular words: AABBCC , AABCBC , ABABCC , ABACBC and ABCABC . 

Regular words in some sense generalize regular brackets sequences (if we consider two-letter alphabet and put similar conditions on regular words, they represent regular brackets sequences). 

Given n , find the number of regular words.

Input

There are mutiple cases in the input file. 

Each case contains n (0 <= n <= 60 ). 

There is an empty line after each case.

Output

Output the number of regular words of length 3n . 

There should be am empty line after each case.

Sample Input

2 3

Sample Output

5 42

Source


Recommend

xhd

题解:

  dp方程很好想:用f[a][b][c]表示A有a个B有b个C有c个的单词的总数量,则f[a][0][0]=1,f[a][b][0]=f[a-1][b][0]+f[a][b-1][0],f[a][b][c]=f[a-1][b][c]+f[a][b-1][c]+f[a][b][c-1],只是要注意f可能过大··所以要用高精度顺便压下位····

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=61;
const int Bit=10000;
int f[N][N][N][30],n;
inline void add(int f1[],int f2[])
{
  int l1,l2;
  for(l1=29;!f1[l1];l1--);for(l2=29;!f2[l2];l2--);
  if(l1<l2)  l1=l2;
  for(int i=1;i<=l1;i++)  f1[i]+=f2[i];
  for(int i=1;i<=l1;i++)  f1[i+1]+=f1[i]/Bit,f1[i]%=Bit;
}
inline void W(int f1[])
{
  int l1;
  for(l1=29;!f1[l1];l1--);
  cout<<f1[l1];
  for(int i=l1-1;i>=1;i--)
  {  
    if(f1[i]>=100&&f1[i]<1000)  putchar(0); 
    else if(f1[i]>=10&&f1[i]<100)   putchar(0),putchar(0);
    else if(f1[i]>=0&&f1[i]<10)  putchar(0),putchar(0),putchar(0);
    cout<<f1[i];  
  }
  cout<<endl;cout<<endl; 
}
inline void getans()
{
  for(int i=1;i<=60;i++)
    for(int j=0;j<=i;j++)
      for(int k=0;k<=j;k++)
      {
        if(j==0)  f[i][j][k][1]=1;
        else if(k==0)
        {  
          add(f[i][j][0],f[i][j-1][0]);add(f[i][j][0],f[i-1][j][0]); 
        }
        else 
        {
          add(f[i][j][k],f[i-1][j][k]);add(f[i][j][k],f[i][j-1][k]);add(f[i][j][k],f[i][j][k-1]);
        }
      }
}
int main()
{
  //freopen("a.in","r",stdin);
  getans();
  while(~scanf("%d",&n))
    W(f[n][n][n]);
  return 0;
}

 


















以上是关于刷题总结——regular words(hdu1502 dp+高精度加法+压位)的主要内容,如果未能解决你的问题,请参考以下文章

HDU1502 Regular Words DP+大数

刷题总结——game(hdu4616)

刷题总结——Human Gene Functions(hdu1080)

刷题总结——you are the one(hdu4283)

刷题总结——Genghis Khan the Conqueror (hdu4126)

刷题总结——Bob's Race(hdu4123 树形dp+st表)