小凸玩密室

小凸玩密室

题解

神仙树形dp。我们定义dp_{i,j}为点亮i后回到i的第j个最小的最小值,g_{i,j}为i的第j个最小的另一个儿子的最小值。之后我们一次遍历整棵树,更新其的dp值,统计答案时再将整个过程的值累加即可。

因为这是一棵完全二叉树,所以我们可以将其从n到1来遍历,不用dfs来遍历,也可达到一样的效果。

源码

#include
#include
#include
#include
#include
#include
#define MAXN 200005
using namespace std;
typedef long long LL;
#define int LL
const LL INF=0x7f7f7f7f7f7f7f7f;
LL n,a[MAXN],b[MAXN],dis[MAXN][20];
LL dp[MAXN][20],g[MAXN][20]; 
int ls[MAXN],rs[MAXN];
#define gc() getchar()
template
inline void read(_T &x)
{
    _T f=1;x=0;char s=gc();
    while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
    while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
    x*=f;
}
int bro(int k,int x)
{
	return (k>>x-1)^1;
}
LL solve()
{
	LL res=INF;
	for(int k=n;k>0;k--)
	{
		if(!ls[k])
			for(int i=1;k>>(i-1);i++)
				g[k][i]=(dis[k][i]+dis[bro(k,i)][1])*a[bro(k,i)];
		else if(!rs[k])
			for(int i=1;k>>(i-1);i++)
				g[k][i]=dis[ls[k]][1]*a[ls[k]]+g[ls[k]][i+1];
		else
			for(int i=1;k>>(i-1);i++)
				g[k][i]=min(dis[ls[k]][1]*a[ls[k]]+g[ls[k]][1]+g[rs[k]][i+1],dis[rs[k]][1]*a[rs[k]]+g[rs[k]][1]+g[ls[k]][i+1]);
	}
	for(int k=n;k>0;k--)
	{
		if(!ls[k])
			for(int i=1;k>>(i-1);i++)
				dp[k][i]=dis[k][i]*a[k>>i];
		else if(!rs[k])
			for(int i=1;k>>(i-1);i++)
				dp[k][i]=dp[ls[k]][i+1]+dis[ls[k]][1]*a[ls[k]];
		else
			for(int i=1;k>>(i-1);i++)
				dp[k][i]=min(dis[ls[k]][1]*a[ls[k]]+g[ls[k]][1]+dp[rs[k]][i+1],dis[rs[k]][1]*a[rs[k]]+g[rs[k]][1]+dp[ls[k]][i+1]);
	}
	for(int k=1;k<=n;k++)
	{
		LL sum=dp[k][1];
		for(int i=1,fa=k>>1;fa;i++,fa>>=1)
		{
			int br=bro(k,i);
			if(br>n) sum+=dis[fa][1]*a[fa>>1];
			else sum+=dis[br][1]*a[br]+dp[br][2];
		}
		res=min(res,sum);
	}
	return res;
}
signed main()
{
	read(n);
	for(int i=1;i<=n;i++) read(a[i]);
	for(int i=2;i<=n;i++) read(b[i]);
	for(int i=1;i<=(n>>1)+1;i++)
	{
		if((i<<1)<=n) ls[i]=i<<1;
		else break;
		if((i<<1|1)<=n) rs[i]=i<<1|1;
	}
	for(int i=2;i<=n;i++)
		dis[i][1]=b[i];
	for(int i=2;i<=18;i++)
		for(int j=n;j>>i;j--)
			dis[j][i]=dis[j][i-1]+dis[j>>(i-1)][1];
	printf("%lld",solve());
    return 0;
}

谢谢!!!

你可能感兴趣的:(#,树,#,树形dp)