hdu5362 Just A String DP

来源:互联网 发布:黑九月 知乎 编辑:程序博客网 时间:2024/06/07 03:38
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 sizem.

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 (1n,m2000).
 

Output
For each case, if the expected number is E, a single integer denotes Emn mod 1000000007.
 

Sample Input
32 23 210 3
 

Sample Output
10401908021
 


如果子串长度为偶数,那么它的个数为奇数的字符种类数为0,如果长度为奇数,那么它的个数为奇数的字符种类数为1.

dp[i][j]表示长度为i,j种字符个数为奇数。

dp[i][j]=dp[i-1][j-1]*(m-j+1)+dp[i-1][j+1]*(j+1)。

最后的答案为子串i是偶数,j=0,i是奇数,j=1补全为n的总数。

#include<iostream>#include<cstdio>#include<set>#define inf 1000000000000000#define ll long longusing namespace std;const ll mod=1000000007;ll dp[2005][2005];ll che[2005];int n,m;int main(){    int t;    scanf("%d",&t);    while(t--) {        scanf("%d%d",&n,&m);        che[0]=1;        for(int i=1;i<=n;i++)            che[i]=che[i-1]*m%mod;        dp[1][0]=0;        dp[1][1]=m;        for(int i=2;i<=n;i++) {            int k=min(i,m);            for(int j=0;j<=k;j++) {                dp[i][j]=0;                if(j-1>=0) {                    dp[i][j]=(dp[i][j]+dp[i-1][j-1]*(m-j+1))%mod;                }                if(j+1<=min(i-1,k)) {                    dp[i][j]=(dp[i][j]+dp[i-1][j+1]*(j+1))%mod;                }            }        }        ll ans=0;        for(int i=1;i<=n;i++) {            ans=(ans+dp[i][i&1]*(n-i+1)%mod*che[n-i]%mod)%mod;        }        printf("%I64d\n",ans);    }    return 0;}


0 0