LOJ-数字转换

题目

题目链接

测试得分:  100

主要算法 :  树型DP(树的最长链)

题干:

   树的最长链

应试策略:

  1. 分析:先预处理出每个数i的约数和sum[i],如果sum[i]<i,则在它们之间连边
  2. 为了方便我们建一条由sum[i]指向i的有向边,长度显然为1.这样一定会构成一棵以1为根树
  3. 于是题目转换为了求树的最长链问题,可以用树形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.构建知识架构,模型体系

原文地址:https://www.cnblogs.com/SeanOcean/p/11313457.html