An interesting question for thieves. Think about converting the cost into something. Watch
If we define the state of leaf node ,}, the state of non leaf node , }, we can get the conclusion by combining the above figure
- The states of leaf nodes x, y (x < y) are the same
- The state of leaf node is the same as lca(x,y), and the cost is 0
- The state of leaf node is different from that of lca(x,y), and the cost is 2f[x,y]
- The states of leaf nodes x, y (x < y) are different, the cost f[x,y]
Technically, the weight of leaf node x about ancestor D is directly defined as H (x, d) = [state of X ≠ state of D] ∑ f[x,y], where y is the leaf node not equal to x governed by D subtree.
In this way, if the state of ancestors is clear, the contribution of X is equal to Σ h(x,d).
Then we consider enumerating the states of ancestors and dp, and set f[x,i] to represent the minimum cost of i 0 state leaf nodes in the X subtree. The transition part is relatively simple, and the reference code is OK.
I didn't make it clear that I will make up tomorrow. Remember to initialize dp array!!!
#include <bits/stdc++.h> #define ls (x<<1) #define rs (x<<1|1) using namespace std; const int inf=0x3f3f3f3f; int n; int cv[2050],ori[2050],tmp[2050]; int dp[2050][2050],v[2050][2050]; int lq[12],rq[12]; void dfs(int x,int l,int r,int set,int dep) { memset(dp[x],inf,sizeof dp[x]); if(l==r) { dep--; dp[x][0]=ori[l]?0:cv[l]; dp[x][1]=ori[l]?cv[l]:0; for(int i=1; i<=dep; ++i) { int mid=(lq[i]+rq[i])>>1; int key=!(1&(set>>(dep-i))); //Different contributions if(l<=mid) dp[x][key]+=v[l][rq[i]]-v[l][mid]; else dp[x][key]+=v[l][mid]-v[l][lq[i]-1]; } return; } int mid=(l+r)>>1,len=r-l+1; lq[dep]=l,rq[dep]=r; dfs(ls,l,mid,set<<1,dep+1); dfs(rs,mid+1,r,set<<1,dep+1); for(int i=0; i<len/2; ++i) for(int j=0; j<=i; ++j) dp[x][i]=min(dp[x][i],dp[ls][j]+dp[rs][i-j]); dfs(ls,l,mid,set<<1|1,dep+1); dfs(rs,mid+1,r,set<<1|1,dep+1); for(int i=len/2; i<=len; ++i) for(int j=0; j<=i; ++j) dp[x][i]=min(dp[x][i],dp[ls][j]+dp[rs][i-j]); } int main() { scanf("%d",&n); n=1<<n; for(int i=1; i<=n; ++i) scanf("%d",ori+i); for(int i=1; i<=n; ++i) scanf("%d",cv+i); for(int i=1; i<=n; ++i) for(int j=i+1; j<=n; ++j) { scanf("%d",&v[i][j]); v[j][i]=v[i][j]; } for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) v[i][j]+=v[i][j-1]; dfs(1,1,n,0,1); int ans=inf; for(int i=0; i<=n; ++i) ans=min(ans,dp[1][i]); printf("%d\n",ans); return 0; }