题目链接:http://codeforces.com/contest/660/problem/E
题意:
现在定义f(a)表示这个a串里面所有不相同的子序列的个数
现在给你n,m,让你用字符集为m,去构造出长度为n的串
然后让你算出所有f(a)的累加
解法:
1:
首先跟着卿学姐学了一种DP的方法
考虑dp
dp[i][j]表示长度为i,以字符j结尾的答案是多少
dp[i][j]=sigma(dp[i-1][k]*2-dp[pre[j]-1][k])
然后这个玩意儿显然对于任意的j的都是一样的,而且pre[j]前面的每个位置都是可能的,这里的dp是个前缀和,所以直接扣除就可以了
那么直接化简为:dp[i]=dp[i-1]*(2m-1)
但是这个dp是没有考虑空串的
那么在加上空串就好了,所以答案就是
dp[i] = dp[i-1]*(2m-1)+m^(i-1)
//CF 660E
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int main()
{
int n, m;
scanf("%d%d", &n, &m);
long long ans = 2*m;
long long tmp = 1;
for(int i = 2; i <= n; i++){
tmp = tmp*m%mod;
ans = (ans*(2*m-1)%mod+tmp+mod)%mod;
}
printf("%d\n", ans);
}
解法2: 然后还有一种组合数学的方法
跪拜:http://www.chanmefang.com/index.php/2016/04/26/cf660e-different-subsets-for-all-tuples/