hdu1502 Regular Words 【dp+高精度加法】

来源:互联网 发布:以太网地址和mac地址 编辑:程序博客网 时间:2024/06/01 10:44

解题思路:
f[a][b][c]表示用a个A,b个B,c个C的方案数,其转移方程为:
if(b==0)f[a][b][c]=1;
else if(c==0)f[a][b][c]=f[a-1][b][c]+f[a][b-1][c];
else f[a][b][c]=f[a-1][b][c]+f[a][b-1][c]+f[a][b][c-1];
其中1an,0ba,0cb;
时间复杂度为O(n3)。

但结果会很大,要用高精度加法,且要压位,详见代码。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<queue>#include<vector>#define ll long longusing namespace std;int getint() {    int i=0,f=1;char c;    for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());    if(c=='-')c=getchar(),f=-1;    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';    return i*f;}const int N=61,p=10000;int n,f[N][N][N][30]; void Add(int f1[],int f2[]){    int l1,l2;    for(l1=29;l1;l1--)if(f1[l1])break;    for(l2=29;l2;l2--)if(f2[l2])break;    if(l1<l2)l1=l2;    for(int i=1;i<=l1;i++)f1[i]+=f2[i];    for(int i=1;i<=l1;i++)        if(f1[i]>=p)f1[i+1]+=f1[i]/p,f1[i]%=p;}void W(int f1[]){    int l1;    for(l1=29;l1;l1--)if(f1[l1])break;    cout<<f1[l1--];    for(int i=l1;i;i--)    {        if(f1[i]<10)putchar('0'),putchar('0'),putchar('0');        else if(f1[i]<100)putchar('0'),putchar('0');        else if(f1[i]<1000)putchar('0');        cout<<f1[i];    }    cout<<'\n'<<'\n';}void pre(){    int a,b,c;    for(a=1;a<=60;a++)        for(b=0;b<=a;b++)            for(c=0;c<=b;c++)            {                if(b==0)f[a][b][c][1]=1;                else if(c==0)                {                    Add(f[a][b][c],f[a-1][b][c]);                    Add(f[a][b][c],f[a][b-1][c]);                }                else                 {                    Add(f[a][b][c],f[a-1][b][c]);                    Add(f[a][b][c],f[a][b-1][c]);                    Add(f[a][b][c],f[a][b][c-1]);                }            }}int main(){    //freopen("lx.in","r",stdin);    pre();    while(scanf("%d",&n)!=EOF)        W(f[n][n][n]);    return 0;}
原创粉丝点击