hdu 1502 大数动态规划

zoj

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1711

hdu

http://acm.hdu.edu.cn/showproblem.php?pid=1502

 

 

题意:给一个字符串,只有ABC组成,并且A、B、C的个数都是n(0<n<=60)个,问你存在多少个组合方式满足条件:任以前X项中,A的个数大于等于B的个数,B的个数大于等于C的个数。

解题:设函数dp[i][j][k]表示该序列中有i个A,j个B,k个C组成,则dp[i][j][k]是有dp[i-1][j][k],dp[i][j-1][k],dp[i][j][k-1]这三个添加过来的,所以动态转移方程式

dp[i][j][k]=dp[i-1][j][k]+dp[i][j-1][k]+dp[i][j][k-1];同时注意,dp的结果很大,要用到大数。

 

将串分成三种情况:末尾为A,末尾为B,末尾为C。则dp[i][t][k]=dp[i-1][t][k]+dp[i][t-1][k]+dp[i][t][k-1]。

初始化,A的数目为0和1时,符合要求的字符串数目,然后由2开始求解当A的数目大于2时的结果

dp[0][0][0] = 1

dp[1][0][0] = 1

dp[1][1][0] = 1

dp[1][1][1] = 1

dp[i][j][k] 表示使用i个A,j个B,k个C满足条件的串的数目

则i小于等于n,j的取值小于等于i,k的取值小于等于j

使用Python 打表

def getAns(n):
    if n < 2:
        return 1

    dp = [
        [
            [0 for i in range(n + 1)]
            for j in range(n + 1)
        ]
        for k in range(n + 1)
    ]

    for i in range(n + 1):
        dp[i][0][0] = 1
    dp[1][1][0] = 1
    dp[1][1][1] = 1

    for i in range(2, n + 1):
        for j in range(i + 1):
            for k in range(j + 1):
                dp[i][j][k] = dp[i - 1][j][k] + dp[i][j - 1][k] + dp[i][j][k - 1]

    return dp[n][n][n]


for i in range(61):
    print(i, getAns(i))

 

使用三维卡特兰数Catalan

220251_grFx_2856757.png

 

def fac(n):
    return 1 if n < 2 else n * fac(n - 1)


for i in range(61):
    print(
        2 * fac(3 * i) // (fac(i) * (fac(i + 1) * fac(i + 2)))
    )


1
1
5
42
462
6006
87516
1385670
23371634
414315330
7646001090
145862174640
2861142656400
57468093927120
1178095925505960
24584089974896430
521086299271824330
11198784501894470250
243661974372798631650
5360563436201569896300
119115896614816702500900
2670926804331443293626900
60386171228363065768956000
1375596980582110638216817680
31554078431506568639711925552
728440733705121725605657358256
16916012593818937850175820875056
394984727560107218767652172156480
9269882950945137003216002357575872
218589820552932101591964442689934272
5177405669064206309480641678873685136
123139887106265725065261170839575261246
2940211742938376804365727956142799686970
70461309651358512358741033490151564263034
1694426732092192797198296281548882854896770
40879953049935966764838175153044218787509460
989318124094680800242093703952690318964293660
24011992526103689868224096174884123328708261100
584414956558400574946623386902564355477176447080
14261150342358043298392602404780869211095488665940
348876433985002864104580005170614922408018905657020
8555006509113973886896694412506009110609925390878620
210257823823361408953856390159370731312558948560177500
5178713915261459187808923452167773648813573133021584000
127816663734641521693312994768720558317819058630953008000
3160890723051037742300958639363743464856851891194511344000
78316111638147520232116305011469771592038383559489541704000
1943917771018304520047172570820410402016667020494472553010000
48334523581589010102952513742546024844918906756931542442556400
1203813957908516875152358489329058054078745007110871474716375280
30029983483935083858438698423851117882968874317657169412268673840
750270153399794678576435057573545926324276055884108148422050727840
18772482769028405636917719941593858764528793976890630506115671775200
470373947038907707302405010980987131831213397364392909428995307126880
11802109943885320655951253002795677125946808879324767545672973160638080
296516920131524804299707608337156053506400465189952712435084509896783040
7459203321130790040650176332416188852363369960068846727881499803410725440
187875141510304732204453155491218970539216498205240765481036372897711988800
4737637890492057297860769571861620074038072983555206964113320603342642320960
119605940186192921945993199027326146131452990076639651225155962772912609414400
3022912056752362939484322031260179006906680462576858197252183463144268821651200

 

打表法,注意每行输出空行

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

char dp[100][100] = {
    "1",
    "1",
    "5",
    "42",
    "462",
    "6006",
    "87516",
    "1385670",
    "23371634",
    "414315330",
    "7646001090",
    "145862174640",
    "2861142656400",
    "57468093927120",
    "1178095925505960",
    "24584089974896430",
    "521086299271824330",
    "11198784501894470250",
    "243661974372798631650",
    "5360563436201569896300",
    "119115896614816702500900",
    "2670926804331443293626900",
    "60386171228363065768956000",
    "1375596980582110638216817680",
    "31554078431506568639711925552",
    "728440733705121725605657358256",
    "16916012593818937850175820875056",
    "394984727560107218767652172156480",
    "9269882950945137003216002357575872",
    "218589820552932101591964442689934272",
    "5177405669064206309480641678873685136",
    "123139887106265725065261170839575261246",
    "2940211742938376804365727956142799686970",
    "70461309651358512358741033490151564263034",
    "1694426732092192797198296281548882854896770",
    "40879953049935966764838175153044218787509460",
    "989318124094680800242093703952690318964293660",
    "24011992526103689868224096174884123328708261100",
    "584414956558400574946623386902564355477176447080",
    "14261150342358043298392602404780869211095488665940",
    "348876433985002864104580005170614922408018905657020",
    "8555006509113973886896694412506009110609925390878620",
    "210257823823361408953856390159370731312558948560177500",
    "5178713915261459187808923452167773648813573133021584000",
    "127816663734641521693312994768720558317819058630953008000",
    "3160890723051037742300958639363743464856851891194511344000",
    "78316111638147520232116305011469771592038383559489541704000",
    "1943917771018304520047172570820410402016667020494472553010000",
    "48334523581589010102952513742546024844918906756931542442556400",
    "1203813957908516875152358489329058054078745007110871474716375280",
    "30029983483935083858438698423851117882968874317657169412268673840",
    "750270153399794678576435057573545926324276055884108148422050727840",
    "18772482769028405636917719941593858764528793976890630506115671775200",
    "470373947038907707302405010980987131831213397364392909428995307126880",
    "11802109943885320655951253002795677125946808879324767545672973160638080",
    "296516920131524804299707608337156053506400465189952712435084509896783040",
    "7459203321130790040650176332416188852363369960068846727881499803410725440",
    "187875141510304732204453155491218970539216498205240765481036372897711988800",
    "4737637890492057297860769571861620074038072983555206964113320603342642320960",
    "119605940186192921945993199027326146131452990076639651225155962772912609414400",
    "3022912056752362939484322031260179006906680462576858197252183463144268821651200",
};

int main(){

    int n;
    while (scanf("%d", &n) == 1){
        printf("%s\n\n", dp[n]);
    }
    return 0;
}

 

转载于:https://my.oschina.net/ahaoboy/blog/1813794

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值