A. 【UNR #2】积劳成疾

链接:http://uoj.ac/contest/40/problem/311

题解:

一道很好的期望题吧

用dp的老思路,枚举最大值将序列分割

想到这个就很简单了

状态f[i][j]表示前i个,最大值为j

f[i][j]=sigma(sigmaf[k][j-1]*sigmaf[i-k][j]*j^贡献次数)

然后显然这个可以前缀和优化一下

写代码莫名其妙写了+=mo

代码:

#include <bits/stdc++.h>
using namespace std;
#define N 500
#define mo 998244353
#define ll long long
ll dp[N][N],js[N],w[N],n,m;
int main()
{
  freopen("noip.in","r",stdin);
  freopen("noip.out","w",stdout);
  std::ios::sync_with_stdio(false);
  cin>>n>>m;
  for (ll i=1;i<=n;i++) cin>>w[i];
  for (ll i=0;i<=n;i++) dp[0][i]=1;
  for (ll i=1;i<=n;i++)
  {
    js[0]=1;
    for (ll j=1;j<=n;j++) js[j]=(js[j-1]*w[i])%mo; 
    for (ll j=1;j<=n;j++)
    {
      dp[j][i]=dp[j][i-1];
      for (ll k=1;k<=j;k++)
        dp[j][i]=(dp[j][i]+(dp[k-1][i-1]*dp[j-k][i])%mo*js[max(0ll,min(k,m)-max(k+m-j-1,0ll))])%mo;
    }
  }
  cout<<dp[n][n]%mo;
  return 0;
}
原文地址:https://www.cnblogs.com/yinwuxiao/p/8727713.html