zoukankan      html  css  js  c++  java
  • bzoj4593: [Shoi2015]聚变反应炉

    这道题的难点其实是在设DP方程,见过就应该会了

    令f0,i表示先激发i的父亲,再激发i,把i的整棵子树都激发的最小费用

    f1,i表示先激发i,再激发i的父亲,把i的整棵子树都激发的最小费用

    设x,y为i的孩子,先激发x再激发i再激发y有

    f0,i=∑(f1,y-cy)+∑f0,x+di-cfa

    f1,i=∑(f1,y-cy)+∑f0,x+di

    其中差的只有cfa,即0<=f1,i-f0,i<=1,对于typeA就容易做了,若两者相等就选f1,它可以消父亲,否则选f0,因为父亲消的次数有限,而即使消了也只是和选f0得到相同的结果

    对于TypeB做树上背包,Fi,j表示第i个点,孩子节点给它贡献了j的最小费用,更新f0,f1

    我码力太弱了。。在判断i是否已经被全部消完的时候f0和1要分开判。。。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    
    struct node
    {
        int x,y,next;
    }a[210000];int len,last[110000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len; 
    }
    
    int n,d[110000],c[110000]; bool type;
    int f[2][110000],F[2100][11000],li[2100],t[11000];
    void dfs(int x,int fr)
    {
        if(type==false)
        {
            f[0][x]=max(d[x]-c[fr],0);
            f[1][x]=d[x];
        }
        else F[x][0]=0;
        int sumc=0;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr)
            {
                dfs(y,x);sumc+=c[y];
                if(type==false)
                {
                    if(f[0][y]==f[1][y])
                    {
                        f[0][x]+=f[1][y]-c[y]*((d[x]-c[fr])>=c[y]);
                        f[1][x]+=f[1][y]-c[y]*(d[x]>=c[y]);
                        d[x]-=c[y];
                    }
                    else
                        f[0][x]+=f[0][y], f[1][x]+=f[0][y];
                }
                else
                {
                    memset(t,63,sizeof(t));
                    for(int i=min(sumc,li[x]);i>=0;i--)t[i]=F[x][i]+f[0][y];
                    for(int i=min(sumc,li[x]);i>=0;i--)
                    {
                        int u=min(sumc,i+c[y]);
                        if(i+c[y]>li[x])t[u]=min(t[u],F[x][i]+f[1][y]);
                        else t[u]=min(F[x][u]+f[0][y],F[x][i]+f[1][y]);
                    }
                    memcpy(F[x],t,sizeof(F[x]));
                    li[x]+=c[y];
                }
            }
        }
        if(type==true)
        {
            for(int i=min(sumc,li[x]);i>=0;i--)
            {
                f[0][x]=min(f[0][x],F[x][i]+max(d[x]-i-c[fr],0));
                f[1][x]=min(f[1][x],F[x][i]+max(d[x]-i,0));
            }
        }
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&d[i]);
        type=false;
        for(int i=1;i<=n;i++)
            scanf("%d",&c[i]),type|=(c[i]>1);
            
        int x,y;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            ins(x,y),ins(y,x);
        }
        memset(f,63,sizeof(f));
        memset(F,63,sizeof(F));
        dfs(1,0);
        printf("%d
    ",f[1][1]);
        
        return 0;
    }
  • 相关阅读:
    Hanoi塔
    采药
    进制转换(大数)
    Load Balancing with NGINX 负载均衡算法
    upstream模块实现反向代理的功能
    epoll
    在nginx启动后,如果我们要操作nginx,要怎么做呢 别增加无谓的上下文切换 异步非阻塞的方式来处理请求 worker的个数为cpu的核数 红黑树
    粘性会话 session affinity sticky session requests from the same client to be passed to the same server in a group of servers
    负载均衡 4层协议 7层协议
    A Secure Cookie Protocol 安全cookie协议 配置服务器Cookie
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10250926.html
Copyright © 2011-2022 走看看