判定转状态+序列问题上树形dp:0909T2

考虑没有括号怎么做。

对于这类+*表达式求值问题,正常思考的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(i1),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的转移不一样而已

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); 
}

其实可以写成矩阵形式来转移

你可能感兴趣的:(动态规划,dp,dp优化)