zoukankan      html  css  js  c++  java
  • 大逃杀(树上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)

  • 相关阅读:
    /dev/tty /dev/ttyS0 /dev/tty0区别
    标准Makefile模板
    Linux Gcc常用命令
    使用mutt+msmtp在Linux命令行界面下发邮件
    DirSync: List of attributes that are synced by the Azure Active Directory Sync Tool
    批量硬关联本地AD帐号与Office云端帐号
    Linux下LDAPSearch的例子
    Powershell连接Office 365各组件的方法
    Shell下的正则表达式 (鸟哥私房菜)
    MySQL数据库管理常用命令
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7652984.html
Copyright © 2011-2022 走看看