srm666 div1 222

博客里以前都是记载的不会的,但是这道题不得不记载,因为最简单的一道题写了一下午,但还是很开心,因为一开始感觉这道题我绝对做不出来,还伤心的怀疑自己的智商,可是硬着头皮做下来,发现,没有人把刀架脖子上逼着我不准写,为啥不写呢?写生气

思路:感觉有点想树形dp,挺简单的。只要分一下返回不返回就行了。

发的是调试时用的代码,所以没有写成类。

(这次没有参考链接得意,今天和队友又去吃了那个有头发和虫子的明味家,虽然卫生……,但是很好吃,在此,不得不又一个严肃的问题,生命和胃那个更重要?)

/*
2015/8/28 20:26
srm666 div1 222 (67.48)
zhangboyu
*/
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 60
#define M 110

int dph[N][M];
int dpb[3][N][M];
int head[N],to[2*N],nextedge[2*N];//head明明没有改变值,却产生变化,可能是因为它前面的那个数组出了问题,可能是开小了
int cou=0;
int L;

void add(int a,int b){
    to[cou]=b;nextedge[cou]=head[a];head[a]=cou++;
}

void dfs(int u,int fa){
    for(int i=0;i<=L;i++){
        dph[u][i]=1;
    }

    //printf("%d %db\n",u,head[u]);
    for(int i=head[u];i!=-1;i=nextedge[i]){
        int v=to[i];
        //printf("%d %d\n",u,v);

        if(v==fa){
            continue;
        }
        else{
            dfs(v,u);
            for(int i=L;i>=0;i--){
                for(int j=0;j<=i-2;j++){
                    dph[u][i]=max(dph[u][i],dph[v][j]+dph[u][i-j-2]);
                }
            }
        }
    }


    for(int i=0;i<=L;i++){
        dpb[2][u][i]=1;
    }
    //printf("%d %da\n",u,head[u]);
    for(int i=head[u];i!=-1;i=nextedge[i]){//枚举走到那个子节点可以不回来
        int vb=to[i];
        //printf("%d %d %dhehe\n",u,vb,nextedge[i]);

        if(vb==fa){
            continue;
        }
        for(int i=0;i<=L;i++){
            dpb[1][u][i]=1;
        }
        for(int j=head[u];j!=-1;j=nextedge[j]){
            int v=to[j];

            //printf("%d %d %dhaha\n",u,v,nextedge[j]);

            if(v==fa){
                continue;
            }

            if(v==vb){
                for(int i=L;i>=0;i--){
                    for(int j=0;j<=i-1;j++){
                        //printf("%d %d %d %d %d %d %d %dha\n",u,i,j,vb,v,dpb[1][u][i],dpb[1][v][j],dpb[1][u][i-j-1]);
                        dpb[1][u][i]=max(dpb[1][u][i],dpb[2][v][j]+dpb[1][u][i-j-1]);
                    }
                }
            }
            else{
                //printf("wo shi da hao ren");
                for(int i=L;i>=0;i--){
                    for(int j=0;j<=i-2;j++){
                        //printf("%d %d %d %d %d %d %d %dhe",u,i,j,vb,v,dpb[1][u][i],dph[v][j],dpb[1][u][i-j-2]);
                        dpb[1][u][i]=max(dpb[1][u][i],dph[v][j]+dpb[1][u][i-j-2]);
                    }
                }
            }
        }

        for(int i=0;i<=L;i++){
            dpb[2][u][i]=max(dpb[1][u][i],dpb[2][u][i]);
            dpb[1][u][i]=0;
        }
    }

    return;
}

int main(){
    int n;
    int b;

    while(scanf("%d",&n)!=EOF){
        memset(head,-1,sizeof(head));
        cou=0;
        //printf("%d\n",n);
        for(int i=1;i<n;i++){
            scanf("%d",&b);
            add(i,b);
            add(b,i);
            //printf("%d %d\n",i,b);
        }
        scanf("%d",&L);

        /*for(int i=head[0];i!=-1;i=nextedge[i]){
            printf("%d\n",to[i]);
        }*/

        memset(dph,0,sizeof(dph));
        memset(dpb,0,sizeof(dpb));
        dfs(0,-1);

        /*for(int i=0;i<n;i++){
            for(int j=0;j<=L;j++){
                printf("%d ",dpb[2][i][j]);
            }
            printf("\n");
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<=L;j++){
                printf("%d ",dph[i][j]);
            }
            printf("\n");
        }*/
        printf("%d\n",dpb[2][0][L]);
    }

    return 0;
}


posted @ 2015-08-28 20:19  buzhidaohahaha  阅读(195)  评论(0编辑  收藏  举报