洛谷P4253：[SCOI2015]小凸玩密室 （DP）

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;

#define P pair<int,long long>
#define MP(x,y) make_pair(x,(long long)y)

const int maxn=200100;
const long long oo=1e17;
typedef long long LL;

vector <P> f[maxn];
LL g[maxn][2];

int a[maxn];
int b[maxn];
int n;

LL Len(int x,int y)
{
if (x==y) return 0;
if (x<y) swap(x,y);
return Len(x>>1,y)+b[x];
}

int main()
{
freopen("D.in","r",stdin);
freopen("D.out","w",stdout);

scanf("%d",&n);
for (int i=1; i<=n; i++) scanf("%d",&a[i]);
for (int i=2; i<=n; i++) scanf("%d",&b[i]);

for (int i=n; i>=1; i--)
{
int x=i<<1,y=x|1;
if (x>n) f[i].push_back( MP(i,0) );
if (x==n) f[i].push_back( MP(x, Len(i,x)*a[x] ) );
if (x<n)
{
LL temp1=oo,temp2=oo;
for (int j=0; j<f[x].size(); j++)
temp1=min(temp1, f[x][j].second+Len(f[x][j].first,y)*a[y] );
for (int j=0; j<f[y].size(); j++)
temp2=min(temp2, f[y][j].second+Len(f[y][j].first,x)*a[x] );
temp1+=Len(i,x)*a[x];
temp2+=Len(i,y)*a[y];

for (int j=0; j<f[y].size(); j++)
f[i].push_back( MP(f[y][j].first,f[y][j].second+temp1) );
for (int j=0; j<f[x].size(); j++)
f[i].push_back( MP(f[x][j].first,f[x][j].second+temp2) );
}
}

for (int i=n; i>=1; i--)
{
g[i][0]=g[i][1]=oo;
int x=i<<1,y=x|1,fa=i>>1;
if (x==n)
g[i][0]=Len(i,x)*a[x]+Len(x,fa)*a[fa],g[i][1]=Len(i,fa)*a[fa];
if (x<n)
{
for (int j=0; j<f[x].size(); j++)
g[i][0]=min(g[i][0],f[x][j].second+Len(f[x][j].first,fa)*a[fa]);
for (int j=0; j<f[y].size(); j++)
g[i][1]=min(g[i][1],f[y][j].second+Len(f[y][j].first,fa)*a[fa]);
g[i][0]+=Len(i,x)*a[x];
g[i][1]+=Len(i,y)*a[y];
}
}

LL ans=oo;
for (int i=n; i>=1; i--)
{
int j=i>>1,x=i;
LL temp=oo;
for (int k=0; k<f[i].size(); k++)
temp=min(temp,f[i][k].second+Len(f[i][k].first,j)*a[j]);
while (j)
{
temp+=g[j][(x&1)^1];
x=j,j>>=1;
}
ans=min(ans,temp);
}
printf("%lld\n",ans);

return 0;
}

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客