2015 Multi-University Training Contest 6(hdu5362 - Just A String)dp求期望

来源:互联网 发布:北京赛车pk10程序源码 编辑:程序博客网 时间:2024/06/15 21:36

Just A String

Problem Description

soda has a random string of length n which is generated by the following algorithm: each of n characters of the string is equiprobably chosen from the alphabet of size m.

For a string s, if we can reorder the letters in string s so as to get a palindrome, then we call s a good string.

soda wants to know the expected number of good substrings in the random string.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains two integers n and m (1≤n,m≤2000).

Output

For each case, if the expected number isE, a single integer denotes Emnmod1000000007.

Sample Input

3
2 2
3 2
10 3

Sample Output

10
40
1908021

题意:如果一个串重排之后是回文串,那么这个串被称为good string,现在有m个字符,构造一个长度为n的串,问有多少字串是good string,求期望
思路:以为最后要乘mn所以相当于求,这样的字串的数量

也就是:nl=1(nl+1)mnlT(l,m)
其中l表示字串长度,T(l,m)表示从m个字符构造长度为l的有多少种方法,乘mnl表示长度为n的出去这个长度为l的,剩下的位置可以随便填
dp[i][j] 表示长度为i的有j种字母是奇数个的串的个数。

那么dp[i][j] 可以从两种情况推得:

  1. dp[i-1][j-1]:表示添加一个原来字母数时偶数的字母字母后,奇数个字母的种数增加了,那么添加的字母只能是已经包含的奇数个数字母以外的字母了有m-j+1;
  2. dp[i-1][j+1] ———– 表示添加一个原来是奇数个的字母,那么奇数个字母的种数减少1,那么只能添加原来是奇数的字母了,有j+1种字母;

所以可得状态转移方程:dp[i][j] = dp[i-1][j-1]]*(m-j+1) + dp[i-1][j+1]*j

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef long long LL;const int maxn=2010;const int maxm=1010;const int MOD=1e9+7;const int INF=0x3f3f3f3f;int N,M;int dp[maxn][maxn];int powM[maxn];int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d%d",&N,&M);        dp[1][0]=0,dp[1][1]=M;        powM[0]=1;        for(int i=1;i<=N;i++){            powM[i]=(LL)powM[i-1]*M%MOD;        }        int j;        for(int i=2;i<N;i++){            dp[i][0]=dp[i-1][1];            dp[i][i]=(LL)dp[i-1][i-1]*(M-i+1)%MOD;            if(i&1){                j=1;            } else {                j=2;            }            for(;j<i;j+=2){                dp[i][j]=(1LL*dp[i-1][j-1]*(M-j+1)%MOD+1LL*dp[i-1][j+1]*(j+1)%MOD)%MOD;            }        }        if(N>1){            dp[N][0]=dp[N-1][1];            dp[N][1]=(1LL*dp[N-1][0]*M%MOD+dp[N-1][2]*2)%MOD;        }        int ans=0;        for(int i=1;i<=N;i++){            ans=(ans+1LL*dp[i][i&1]*(N-i+1)%MOD*powM[N-i]%MOD)%MOD;        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击