bzoj4446[Scoi2015]小凸玩密室

4446: [Scoi2015]小凸玩密室

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 419  Solved: 173
[Submit][Status][Discuss]

Description

小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡。点亮所有灯

泡即可逃出密室。每个灯泡有个权值Ai,每条边也有个权值bi。点亮第1个灯泡不需要花费,之后每点亮4

个新的灯泡V的花费,等于上一个被点亮的灯泡U到这个点V的距离Du,v,乘以这个点的权值Av。在点灯

的过程中,要保证任意时刻所有被点亮的灯泡必须连通,在点亮一个灯泡后必须先点亮其子树所有灯泡才能点亮其他灯泡。请告诉他们,逃出密室的最少花费是多少。

Input

第1行包含1个数n,代表节点的个数

第2行包含n个数,代表每个节点的权值ai。(i=l,2,…,n)

第3行包含n-l个数,代表每条边的权值bi,第i号边是由第(i+1)/2号点连向第i+l号点的边。

(i=l,2...N-1)

Output

输出包含1个数,代表最少的花费。

Sample Input

3
5 1 2
2 1

Sample Output

5

HINT

对于100%的数据,1≤N≤2×105,1<Ai,Bi≤10^5

神题。
https://www.cnblogs.com/CXCXCXC/p/5312237.html

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define N 200010
 4 using namespace std;
 5 ll f[N][20],g[N][20];
 6 int n,v[N],w[N],dep[N],d[N];
 7
 8 int main(){
 9     scanf("%d",&n);dep[1]=1;
10     for(int i=1;i<=n;i++)
11     scanf("%d",&v[i]);
12     for(int i=2;i<=n;i++){
13         scanf("%d",&w[i]);
14         dep[i]=dep[i>>1]+1;
15         d[i]=d[i>>1]+w[i];
16     }
17     for(int i=n;i;i--){
18         if((i<<1)>n){
19             for(int j=0;j<=dep[i];j++){
20                 int fa=i>>(dep[i]-j+1),to=(i>>(dep[i]-j))^1;
21                 f[i][j]=1ll*(d[i]+d[to]-2*d[fa])*v[to];
22             }
23         }
24         else if((i<<1)==n){
25             for(int j=0;j<=dep[i];j++){
26                 int to=i<<1;
27                 f[i][j]=f[to][j]+1ll*v[to]*w[to];
28             }
29         }
30         else{
31             int ls=i<<1,rs=ls|1;
32             for(int j=0;j<=dep[i];j++)
33             f[i][j]=min(1ll*v[ls]*w[ls]+f[ls][dep[ls]]+f[rs][j],1ll*v[rs]*w[rs]+f[rs][dep[rs]]+f[ls][j]);
34         }
35     }
36     for(int i=n;i;i--){
37         if((i<<1)>n){
38             for(int j=0;j<=dep[i];j++){
39                 int fa=i>>(dep[i]-j);
40                 g[i][j]=1ll*(d[i]-d[fa])*v[fa];
41             }
42         }
43         else if((i<<1)==n){
44             int s=i<<1;
45             for(int j=0;j<=dep[i];j++)
46             g[i][j]=1ll*v[s]*w[s]+g[s][j];
47         }
48         else{
49             int ls=i<<1,rs=ls|1;
50             for(int j=0;j<=dep[i];j++)
51             g[i][j]=min(1ll*v[ls]*w[ls]+f[ls][dep[ls]]+g[rs][j],1ll*v[rs]*w[rs]+f[rs][dep[rs]]+g[ls][j]);
52         }
53     }
54     ll ans=g[1][0];
55     for(int i=2;i<=n;i++){
56         ll ret=g[i][dep[i]-1];
57         for(int x=i;x>1;x>>=1){
58             int y=x^1;
59             if(y>n)ret+=1ll*v[x>>2]*w[x>>1];
60             else ret+=1ll*v[y]*w[y]+g[y][dep[y]-2];
61         }
62         ans=min(ans,ret);
63     }
64     printf("%lld\n",ans);
65     return 0;
66 }

原文地址:https://www.cnblogs.com/wsy01/p/8324754.html

时间: 2024-10-09 10:10:59

bzoj4446[Scoi2015]小凸玩密室的相关文章

[BZOJ4446]SCoi2015 小凸玩密室 树形DP(烧脑高能预警)

4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec  Memory Limit: 128 MB Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要花费,之后每点亮4 个(1个)新的灯泡V的花费,等于上一个被点亮的灯泡U到这个点V的距离Du,v,乘以这个点的权值Av.在点灯 的过程中,要保证任意时刻所有被点亮的灯泡必须连

[bzoj4446] [loj#2009] [Scoi2015] 小凸玩密室

Description 小凸和小方相约玩密室逃脱,这个密室是一棵有 \(n\) 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 \(Ai\) ,每条边也有个权值 \(bi\) .点亮第 1 个灯泡不需要花费,之后每点亮 1 个新的灯泡 \(V\) 的花费,等于上一个被点亮的灯泡 \(U\) 到这个点 \(V\) 的距离 \(Du,v\),乘以这个点的权值 \(Av\) .在点灯的过程中,要保证任意时刻所有被点亮的灯泡必须连通,在点亮一个灯泡后必须先点亮其子树所

LibreOJ #2009. 「SCOI2015」小凸玩密室

二次联通门 : LibreOJ #2009. 「SCOI2015」小凸玩密室 /* LibreOJ #2009. 「SCOI2015」小凸玩密室 树形dp 做到这么正常的题突然感觉好不适应.... 考虑转移 f[x][y] 表示从x点转移到y点的代价 则我们需要处理出以x为根的子树的代价 讨论处理一下即可(有没有左儿子,有没有右儿子,或是都有) 但是这样转移是O(N^2)的 所以我们考虑优化 显然有很多转移是不需要的 比如y在x的子树中时就没必要转移 那么考虑优化 设g[x][i]表示走完x的子

—Libre#2009. 「SCOI2015」小凸玩密室

#2009. 「SCOI2015」小凸玩密室 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 小凸和小方相约玩密室逃脱,这个密室是一棵有 n nn 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 Ai A_iA?i??,每条边也有个权值 bi b_ib?i??. 点亮第 1 11 个灯泡不需要花费,之后每点亮一个新的灯泡 V VV 的花费,等于上一个被点亮的

[Scoi2015]小凸玩矩阵

bzoj 4443: [Scoi2015]小凸玩矩阵 http://www.lydsy.com/JudgeOnline/problem.php?id=4443 Time Limit: 10 Sec  Memory Limit: 128 MB Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少. Input 第一行给出三个整数N,M,K 接下来N

【BZOJ4443】[Scoi2015]小凸玩矩阵 二分+二分图最大匹配

[BZOJ4443][Scoi2015]小凸玩矩阵 Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少. Input 第一行给出三个整数N,M,K 接下来N行,每行M个数字,用来描述这个矩阵 Output 如题 Sample Input 3 4 2 1 5 6 6 8 3 4 3 6 8 6 3 Sample Output 3 HINT 1<

4443: [Scoi2015]小凸玩矩阵

4443: [Scoi2015]小凸玩矩阵 Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少. Input 第一行给出三个整数N,M,K 接下来N行,每行M个数字,用来描述这个矩阵 Output 如题 Sample Input 3 4 2 1 5 6 6 8 3 4 3 6 8 6 3 Sample Output 3 HINT 1<=K&l

小凸玩密室题解

小凸玩密室题解 恶心题啊-- 开始连题意都看不懂, 看了会题解的题意简化,结果理解错了题意,说多了都是泪啊- 首先说说题意吧: 点亮一盏灯后,只有点亮完子树内所有灯后才能点其他灯,而且点亮的灯要求要连通. -->下一步一定点两个儿子之一,先点完这个儿子的子树再点另一个儿子. 然而,上一盏灯点什么十分不好求,贡献算不出(一个点子树内有多个层数相同的子孙). 但是,我们可以通过上一盏灯算下一盏灯的贡献啊(每个点只有一个层数一定的父辈). 所以点完这个点后,我们只有两种情况: 1.我们点完这个点后构成

「SCOI2015」小凸玩密室

题目描述 小凸和小方相约玩密室逃脱,这个密室是一棵有 $n$ 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 $A_i$,每条边也有个权值 $b_i$. 点亮第 $1$ 个灯泡不需要花费,之后每点亮一个新的灯泡 $V$ 的花费,等于上一个被点亮的灯泡 $U$ 到这个点 $V$ 的距离 $D(u, v)$,乘以这个点的权值 $A_v$. 在点灯的过程中,要保证任意时刻所有被点亮的灯泡必须连通,在点亮一个灯泡后必须先点亮其子树所有灯泡才能点亮其他灯泡.请告诉他们,