牛客练习110-D,E
题目链接:https://ac.nowcoder.com/acm/contest/54129/D
比赛的时候dp状态方程想错了,一直在做无用功。
思路:设\(dp[i]\)为用了i次魔法的期望值,递推地做即可。
hard版本:考虑字符串中的每一个字母对答案的贡献,每位数字没被选择的概率为\(p = {(n-1)^k/n}^k\),被选择的概率为\(p_1 = 1-p\),而变几次对答案是没有任何影响的,所以我们枚举字符串求每一位的贡献即可。
代码:
//easy版本
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
map<char,int>M;
long long qmod(long long x,long long y){
long long res = 1;
while(y){
if (y&1) res = res*x%mod;
y = y>>1;
x = x*x%mod;
}
return res;
}
long long dp[2000];
int main(){
int n,k;
cin>>n>>k;
string s;
cin>>s;
M['y'] = 1;
M['w'] = 1;
M['i'] = 1;
M['a'] = 1;
M['k'] = 1;
long long v1 = 5*qmod(26,mod-2)%mod;
long long v2 = 21*qmod(26,mod-2)%mod;
long long t = qmod(n,mod-2);
for (int i=0;i<n;i++){
if (M.count(s[i])) dp[0]++;
}
for (int i=1;i<=k;i++){
dp[i] = dp[i-1];
dp[i] = (dp[i]-dp[i-1]*t%mod*v2%mod+mod)%mod;
dp[i] = (dp[i]+(n-dp[i-1]+mod)*t%mod*v1%mod)%mod;
}
cout<<dp[k]<<'\n';
}
//hard版本
#include<bits/stdc++.h>
using namespace std;
const long long mod = 1e9+7;
set<char>S;
long long qmod(long long x,long long y){
long long res = 1;
while(y){
if (y&1) res = res*x%mod;
y = y>>1;
x = x*x%mod;
}
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
long long n,k;
cin>>n>>k;
string s;
cin>>s;
long long ans = 0;
long long p = qmod((n-1)*qmod(n,mod-2)%mod,k);
long long q = (1-p+mod)%mod;
long long v = 5*qmod(26,mod-2)%mod;
S.insert('y');
S.insert('w');
S.insert('k');
S.insert('a');
S.insert('i');
for (int i=0;i<n;i++){
if (S.count(s[i])){
ans = (ans+p)%mod;
}
ans = (ans+q*v%mod)%mod;
}
cout<<ans;
}
浙公网安备 33010602011771号