bzoj4027: [HEOI2015]兔子与樱花

TreeDP与贪心算法
本文介绍了一种结合TreeDP与贪心策略解决特定问题的方法。通过对子树进行排序并优先删除值较小的节点来优化解决方案。代码示例展示了如何实现这一算法。

这题以前好像是做过的。

很容易发现就是treeDP了。

然后需要一点贪心的思想,对于当前以x为根的子树,删除任意的子节点,实际上答案都是+1,所以可以排序一下,然后先删那些值小的点。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int n,m;
struct node
{
    int x,y,next;
}a[4100000];int len,last[2100000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}

int ans;
int d[2100000],son[2100000];
int tlen,tt[2100000];
void treedp(int x)
{
    for(int k=last[x];k;k=a[k].next)treedp(a[k].y);
    
    tlen=0;
    for(int k=last[x];k;k=a[k].next)tt[++tlen]=d[a[k].y];
    sort(tt+1,tt+tlen+1);
    
    for(int i=1;i<=tlen;i++)
    {
        if(d[x]+tt[i]-1<=m)
            d[x]=d[x]+tt[i]-1, ans++;
        else break;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&d[i]);
    
    int x;
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&son[i]);
        for(int j=1;j<=son[i];j++)
            scanf("%d",&x), ins(i,x+1);
        d[i]+=son[i];
    }
    
    ans=0;treedp(1);
    printf("%d\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/AKCqhzdy/p/8504669.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值