【HDU5482】Numquam vincar,暴力(da biao)预处理+组合数

Time:2016.05.26
Author:xiaoyimi
转载注明出处谢谢


传送门
思路:
观察到n,m比较小,我们可以暴力+打表一波
k的范围比较大,但是我们比较容易想到,当k很大时,实际上就是在原来的基础上乘以 Cnk ,所以暴力枚举所有长度为i,不同字符为k的串,然后加到f[i][j][k],j就是该串的不同子串数目
暴力大概跑了4s左右
(f[i][j][k]:字符串长度为i,不同子串数目为j,由k个不同字符构成的串的数量)
对于ans(n,m,k)来说,它就是
f[n][m][i]Cik 其中i=1..min(n,k)
注意:
暴力代码被我误删了……懒得重新打一遍,所以没法给大家看暴力代码了……
代码:

#include<cstdio>
#include<iostream>
#define mo 1000000007
#define LL long long
using namespace std; 
int n,m,k,ans;
int a[18],f[12][102][12],P[12];
void work()
{
    scanf("%d%d%d",&n,&m,&k);
    P[1]=k;
    ans=0;
    for (int i=2;i<=n;i++) P[i]=(LL)P[i-1]*(k-i+1)%mo;
    for (int i=1;i<=min(n,k);i++)
        ans=(ans+(LL)P[i]*f[n][m][i]%mo)%mo;
    printf("%d\n",ans);
}
int main()
{
f[1][1][1]=1;
f[2][2][1]=1;
f[2][3][2]=1;
f[3][3][1]=1;
f[3][5][2]=3;
f[3][6][3]=1;
f[4][4][1]=1;
f[4][7][2]=3;
f[4][8][2]=4;
f[4][9][3]=6;
f[4][10][4]=1;
f[5][5][1]=1;
f[5][9][2]=3;
f[5][11][2]=10;
f[5][12][2]=2;
f[5][12][3]=6;
f[5][13][3]=19;
f[5][14][4]=10;
f[5][15][5]=1;
f[6][6][1]=1;
f[6][11][2]=3;
f[6][14][2]=10;
f[6][15][2]=9;
f[6][15][3]=6;
f[6][16][2]=9;
f[6][17][3]=45;
f[6][18][3]=39;
f[6][18][4]=10;
f[6][19][4]=55;
f[6][20][5]=15;
f[6][21][6]=1;
f[7][7][1]=1;
f[7][13][2]=3;
f[7][17][2]=10;
f[7][18][3]=6;
f[7][19][2]=21;
f[7][20][2]=10;
f[7][21][2]=19;
f[7][21][3]=45;
f[7][22][3]=38;
f[7][22][4]=10;
f[7][23][3]=154;
f[7][24][3]=58;
f[7][24][4]=126;
f[7][25][4]=214;
f[7][25][5]=15;
f[7][26][5]=125;
f[7][27][6]=21;
f[7][28][7]=1;
f[8][8][1]=1;
f[8][15][2]=3;
f[8][20][2]=10;
f[8][21][3]=6;
f[8][23][2]=20;
f[8][24][2]=26;
f[8][25][2]=8;
f[8][25][3]=45;
f[8][26][2]=36;
f[8][26][4]=10;
f[8][27][2]=24;
f[8][27][3]=85;
f[8][28][3]=159;
f[8][29][3]=287;
f[8][29][4]=126;
f[8][30][3]=312;
f[8][30][4]=100;
f[8][30][5]=15;
f[8][31][3]=72;
f[8][31][4]=807;
f[8][32][4]=658;
f[8][32][5]=280;
f[8][33][5]=755;
f[8][33][6]=21;
f[8][34][6]=245;
f[8][35][7]=28;
f[8][36][8]=1;
f[9][9][1]=1;
f[9][17][2]=3;
f[9][23][2]=10;
f[9][24][3]=6;
f[9][27][2]=21;
f[9][28][2]=8;
f[9][29][2]=35;
f[9][29][3]=45;
f[9][30][2]=10;
f[9][30][4]=10;
f[9][31][2]=53;
f[9][32][2]=28;
f[9][32][3]=84;
f[9][33][2]=67;
f[9][33][3]=218;
f[9][34][2]=20;
f[9][34][3]=24;
f[9][34][4]=126;
f[9][35][3]=611;
f[9][35][5]=15;
f[9][36][3]=590;
f[9][36][4]=220;
f[9][37][3]=907;
f[9][37][4]=818;
f[9][38][3]=468;
f[9][38][4]=1382;
f[9][38][5]=280;
f[9][39][3]=72;
f[9][39][4]=3496;
f[9][39][5]=211;
f[9][39][6]=21;
f[9][40][4]=1718;
f[9][40][5]=2758;
f[9][41][5]=3687;
f[9][41][6]=540;
f[9][42][6]=2085;
f[9][42][7]=28;
f[9][43][7]=434;
f[9][44][8]=36;
f[9][45][9]=1;
f[10][10][1]=1;
f[10][19][2]=3;
f[10][26][2]=10;
f[10][27][3]=6;
f[10][31][2]=20;
f[10][32][2]=9;
f[10][33][3]=45;
f[10][34][2]=38;
f[10][34][4]=10;
f[10][35][2]=31;
f[10][36][2]=42;
f[10][37][2]=30;
f[10][37][3]=86;
f[10][38][2]=68;
f[10][38][3]=152;
f[10][39][2]=80;
f[10][39][3]=136;
f[10][39][4]=126;
f[10][40][2]=96;
f[10][40][3]=30;
f[10][40][5]=15;
f[10][41][2]=76;
f[10][41][3]=644;
f[10][42][2]=8;
f[10][42][3]=769;
f[10][42][4]=218;
f[10][43][3]=958;
f[10][43][4]=967;
f[10][44][3]=1993;
f[10][44][4]=48;
f[10][44][5]=280;
f[10][45][3]=2137;
f[10][45][4]=2962;
f[10][45][6]=21;
f[10][46][3]=1762;
f[10][46][4]=4666;
f[10][46][5]=459;
f[10][47][3]=576;
f[10][47][4]=9382;
f[10][47][5]=2777;
f[10][48][3]=36;
f[10][48][4]=11778;
f[10][48][5]=4435;
f[10][48][6]=540;
f[10][49][4]=3948;
f[10][49][5]=19074;
f[10][49][6]=390;
f[10][49][7]=28;
f[10][50][5]=15485;
f[10][50][6]=7435;
f[10][51][6]=14441;
f[10][51][7]=945;
f[10][52][7]=4907;
f[10][52][8]=36;
f[10][53][8]=714;
f[10][54][9]=45;
f[10][55][10]=1;
    int t;
    scanf("%d",&t);
    while (t--) work(); 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值