• 大逃杀(树上dp)


    这道题和宝藏差不多吧,转移的时候比较麻烦的。

    代码中分量很多种情况。

    h更新比较麻烦

    这两幅图表示了双边更新中3,4连个h更新,下面比较好理解的吧。

     1 #include<cstring>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstdio>
     6 #define N 307
     7 using namespace std;
     8 
     9 const int inf=1000000009;
    10 
    11 int n,m,ans=-inf;
    12 int w[N],t[N];
    13 int f[N][N],g[N][N],h[N][N];
    14 int cnt,head[N],next[N*2],rea[N*2],val[N*2];
    15 
    16 void add(int u,int v,int fee)
    17 {
    18     next[++cnt]=head[u],head[u]=cnt;
    19     rea[cnt]=v,val[cnt]=fee;
    20 }
    21 void dfs(int u,int fa)
    22 {
    23     for (int i=0;i<=m;i++)
    24         f[u][i]=g[u][i]=h[u][i]=(i>=t[u]?w[u]:-inf);//初始化 
    25     for (int i=head[u];i!=-1;i=next[i])//这次均摊是O(1)  
    26     {
    27         int v=rea[i],fee=val[i];
    28         if (v==fa) continue;
    29         dfs(v,u);
    30         for (int j=m;j>=fee;j--)
    31             for (int k=0;k<=j-fee;k++)
    32             {
    33                 int nowf=f[u][j],nowg=g[u][j],nowh=h[u][j];
    34                 if (j-2*fee-k>=0)
    35                 {
    36                     nowf=max(nowf,f[u][j-2*fee-k]+f[v][k]);
    37                     nowg=max(nowg,g[u][j-2*fee-k]+f[v][k]);
    38                     nowh=max(nowh,h[u][j-2*fee-k]+f[v][k]);//图上注释 
    39                     nowh=max(nowh,f[u][j-2*fee-k]+h[v][k]);//图上注释 
    40                 }
    41                 nowg=max(nowg,f[u][j-k-fee]+g[v][k]);//直接进入这个v结束 
    42                 nowh=max(nowh,g[u][j-k-fee]+g[v][k]);//直接进入这个v结束 
    43                 f[u][j]=nowf,g[u][j]=nowg,h[u][j]=nowh;
    44             }
    45     }
    46 //    cout<<u<<" "<<h[u][m]<<" "<<f[u][m]<<" "<<g[u][m]<<endl;
    47     ans=max(ans,h[u][m]);
    48     if (fa==-1) printf("%d",ans);
    49 }
    50 int main()
    51 {
    52     memset(head,-1,sizeof(head));
    53     scanf("%d%d",&n,&m);
    54     for (int i=1;i<=n;i++) scanf("%d",&w[i]);
    55     for (int i=1;i<=n;i++) scanf("%d",&t[i]);
    56     for (int i=1,x,y,z;i<n;i++)
    57     {
    58         scanf("%d%d%d",&x,&y,&z);
    59         add(x,y,z),add(y,x,z);
    60     }
    61     dfs(1,-1);
    62 }

    转移O(n^2),遍历O(n),然后就是O(n^3)

  • 相关阅读:
    .Net 框架培训
    根据 XSD生成 Data Contract之怪现象
    WCF performance
    IIS7 performance
    【原】[SQL function] SQL Server Split Function
    【原】[Data.Common.Format] 格式化传入的float(浮点型)字符串
    【原】[Crystal Reports] 当前一条记录与前一条记录比较
    【转】C#中处理XML文档的方法
    【原】Crystal Reports水晶报表 格式化传入的float字符串
    【转】[ASP] 用 ASP 创建 GUID
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7652984.html
Copyright © 2020-2023  润新知