树的遍历 树形DP
将题意转化为树形结构
计算节点i至根节点距离
所谓记忆化搜索, 就是将已经计算出的值, 进行存储, 防止后续重复计算
对于该题, 若树形结构为
1
1
1条具有
n
n
n个节点的链
若不采取记忆化搜索
搜索过程中, 叶子节点需要计算
n
n
n次,叶子节点父节点需要计算
n
−
1
n-1
n−1次, ……, 最终时间复杂度为
O
(
N
2
)
O(N{^2})
O(N2)
若不采取记忆化搜索
每个节点只需计算一次, 最终时间复杂度为
O
(
N
)
O(N)
O(N)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include
#define int long long
#define x first
#define y second
#define ump unordered_map
#define pq priority_queue
#define rep(i, a, b) for(int i=a;i=b;--i)
using namespace std;
typedef pair PII;
const int N = 100005;
//int t, n, m, cnt, ans;
// l[i]存储节点i的左节点 r[i]存储节点i的左节点 v[i]存储节点i的权值 h[i]存储节点i的高度 idx存储当前已用到的节点个数
int n;
double r, p;
// f[i]存储编号为i的节点的父节点 d[i] 存储编号为i的节点至父节点的距离 cnt[i]存储节点i卖出的产品数
int f[N], d[N], cnt[N];
inline int rd(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put(int x) {
if(x<0) putchar('-'),x=-x;
if(x>=10) put(x/10);
putchar(x%10^48);
}
int dfs(int u){
if(d[u]!=-1){
return d[u];
}
if(f[u]==-1){
return d[u]=0;
}
return d[u]=dfs(f[u])+1;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
memset(f, -1, sizeof f);
scanf("%lld %lf %lf", &n, &p, &r);
rep(i, 0, n){
int k, id, son;
scanf("%lld", &k);
rep(j, 0, k){
scanf("%lld", &son);
f[son]=i;
}
if(!k){
scanf("%lld", &cnt[i]);
}
}
memset(d, -1, sizeof d);
double res=0;
rep(i, 0, n){
if(cnt[i]){
res+=cnt[i]* p*pow(1+r/100, dfs(i));
}
}
printf("%.1lf", res);
return 0;
}
AcWing 1565. 供应链总销售额(PAT甲级辅导课)y总视频讲解
原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈