题目
测试得分: 100
主要算法 : 树型DP(树的最长链)
题干:
树的最长链
应试策略:
- 分析:先预处理出每个数i的约数和sum[i],如果sum[i]<i,则在它们之间连边
- 为了方便我们建一条由sum[i]指向i的有向边,长度显然为1.这样一定会构成一棵以1为根树
- 于是题目转换为了求树的最长链问题,可以用树形DP求解.
代码
#include<stdio.h> #include<stdlib.h> #define FORa(i,s,e) for(int i=s;i<=e;i++) #define FORs(i,s,e) for(int i=s;i>=e;i--) using namespace std; const int N=51000; int n,ans,sum[N+1],d1[N+1],d2[N+1]; inline int max(int fa,int fb){return fa>fb?fa:fb;} int main() { /*分析:先预处理出每个数i的约数和sum[i],如果sum[i]<i,则在它们之间连边 为了方便我们建一条由sum[i]指向i的有向边,长度显然为1.这样一定会构成一棵以1为根树 于是题目转换为了求树的最长链问题,可以用树形DP求解.*/ scanf("%d",&n); FORa(i,1,n) FORa(j,2,n/i) sum[i*j]+=i; FORs(i,n,1) { if(sum[i]<i) if(d1[i]+1>d1[sum[i]]) d2[sum[i]]=d1[sum[i]],d1[sum[i]]=d1[i]+1; else if(d1[i]+1>d2[sum[i]]) d2[sum[i]]=d1[i]+1; } FORa(i,1,n) ans=max(d1[i]+d2[i],ans); printf("%d",ans); return 0; }
总结:
1.确定建立模型
2.构建知识架构,模型体系