HDU 6065 RXD, tree and sequence 分析+01背包

//给你个树,序列,分隔 序列k段, 求 每段lca 深度之和最小。 
/*
   求[i,j]的LCA 我们可以通过求[i,j-1] and j的LCA ;
    deep(lca) <=deep[i,j];
    deep(lca) =min(deep(i,j-1),lca(j,j-1);
	我们可以通过 lca(pair(i,i+1)) 计算出所有区间的lca;
	假设 区间 3,4,5,6;
	lca = min{lca(3,4)....lca(5,6)}
	假设区间 3,4,5,6,7,8 最优解分成了两端, 3,4为一段答案, 7,8 为另一段答案;
	 那显然 lca(3,4),lca(7,8)<=lca(4,5),lca(5,6),lca(6,7)
	 5,6,分给那个区间都没有影响
	 所以可以  假设每次分配时,都以当前位置作为分隔点,进行状态转移。
	 dp[i][j]  前i 个 分了 j 段
	 dp[i][j] =min{dp[i][j-1] ,dp[i-1][j-1]+deep(i),dp[i-2][j-1] +deep(lca(i,j))}
*/ 
#include   
using namespace std;  
typedef pair pii;  
const int maxn=300005;  
int n,K,a[maxn],f[maxn],dep[maxn],dp[3][maxn],lca[maxn];  
vector ask[maxn];  
vector G[maxn];  
void init() {  
    for (int i=1;i<=n;++i) {  
        f[i]=i;  
        G[i].clear();  
        ask[i].clear();  
    }  
    for (int i=1;i=2)  
                    dp[i%3][j]=min(dp[i%3][j],dp[(i+1)%3][j-1]+lca[i]);  
            }  
        }  
        printf("%d\n",dp[n%3][K]);  
    }  
    return 0;  
}  

你可能感兴趣的:(DP-经典模型,图论-LCA)