考虑没有括号怎么做。
对于这类+*表达式求值问题,正常思考的dp是状态 O ( n ) O(n) O(n),总共为 O ( n 2 ) O(n^2) O(n2) 的
但其实可以对于每个dp记录两个值,分别为答案dp,和后面的乘积和g
如果接乘号,就是 [ j ] ( d p , g ) → [ j ] ( d p + g ( i − 1 ) , g i ) [j](dp,g)\to[j](dp+g(i-1),gi) [j](dp,g)→[j](dp+g(i−1),gi)
之所以要-1,是因为g我们在之前的dp已经囊括了
接加号, [ j ] ( d p , g ) → [ j + 1 ] ( d p + i , i ) [j](dp,g)\to[j+1](dp+i,i) [j](dp,g)→[j+1](dp+i,i)
然后考虑有括号,显然可以建一个括号树,然后类似树形dp的过程。只不过j的转移不一样而已
令当前所有情况答案为dp,所有情况最后的乘积和为g就行了
for(j=0; j<=w[u]; ++j) for(k=0; k<=w[v]; ++k) {
Mod(dps[j+k+1], dp[u][j]*C[w[v]][k]%mo+dp[v][k]*C[w[u]][j]%mo);
Mod(gs[j+k+1], dp[v][k]*C[w[u]][j]%mo);
Mod(dps[j+k], (dp[u][j]-g[j])*C[w[v]][k]%mo+g[j]*dp[v][k]%mo);
Mod(gs[j+k], g[j]*dp[v][k]%mo);
}
其实可以写成矩阵形式来转移