• BZOJ 1017 魔兽地图DotR(树形DP)


    题意:有两类装备,高级装备A和基础装备B。现在有m的钱。每种B有一个单价和可以购买的数量上限。每个Ai可以由Ci种其他物品合成,给出Ci种其他物品每种需要的数量。每个装备有一个贡献值。求最大的贡献值。已知物品的合成路线是一个严格的树模型。即有一种物品不会合成其他任意物品,其余物品都会仅仅可用作合成另外一种物品

    思路:f[i][j][k],代表第i个物品,花费了j,向上提供k个i物品。

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 int f[55][2005][105];
     7 int num[20005],a[20005],b[20005],c[105][105],d[105][105];
     8 int n,m,vis[200005],dp[55][2005],w[20005],pd[20005];
     9 void dfs(int x){
    10     if (!num[x]){
    11         b[x]=std::min(b[x],m/a[x]);
    12         for (int i=0;i<=b[x];i++)
    13          for (int j=0;j<=i;j++)
    14           f[x][i*a[x]][j]=w[x]*(i-j);
    15         return;  
    16     }
    17     b[x]=0x7fffffff;
    18     for (int i=1;i<=num[x];i++){
    19         int pur=c[x][i];
    20         dfs(pur);
    21         b[x]=std::min(b[x],b[pur]/d[x][i]);
    22         a[x]+=d[x][i]*a[pur];
    23     }
    24     b[x]=std::min(b[x],m/a[x]);
    25     for (int t=0;t<=b[x];t++){
    26         memset(dp,-0x3f3f3f3f,sizeof dp);
    27         dp[0][0]=0; 
    28         for (int i=1;i<=num[x];i++)
    29          for (int j=0;j<=m;j++)
    30           for (int k=0;k<=j;k++)
    31            dp[i][j]=std::max(dp[i][j],dp[i-1][j-k]+f[c[x][i]][k][t*d[x][i]]);
    32         for (int j=0;j<=m;j++)
    33          for (int k=0;k<=t;k++)
    34           f[x][j][k]=std::max(f[x][j][k],dp[num[x]][j]+(t-k)*w[x]);
    35     }
    36 }
    37 int main(){
    38     char s[20];
    39     scanf("%d%d",&n,&m);
    40     for (int i=1;i<=n;i++){
    41         scanf("%d",&w[i]);
    42         scanf("%s",s+1);
    43         if (s[1]=='A') pd[i]=1;else pd[i]=0;
    44         num[i]=0;
    45         if (pd[i]==0) {
    46           scanf("%d%d",&a[i],&b[i]);
    47           num[i]=0;
    48           continue;
    49         }
    50         scanf("%d",&num[i]);
    51         for (int j=1;j<=num[i];j++){
    52          scanf("%d%d",&c[i][j],&d[i][j]);
    53          vis[c[i][j]]=1; 
    54         }
    55     }
    56     int i;
    57     for (i=1;i<=n;i++) if (!vis[i]) break;
    58     int root=i;
    59     memset(f,-0x3f3f3f3f,sizeof f);
    60     dfs(root);
    61     int ans=0;
    62     for (int i=0;i<=m;i++)
    63      for (int j=0;j<=b[root];j++)
    64       ans=std::max(ans,f[root][i][j]);
    65     printf("%d
    ",ans);  
    66 }
  • 相关阅读:
    SSH批量部署服务
    rsync配置
    你到底有没有资本
    QT4.8.5 源码编译记录
    kernel 4.4.12 移植 HUAWEI MU609 Mini PCIe Module
    AM335x 添加 HUAWEI MU609 Mini PCIe Module,并用pppd 启动相关设备
    u-boot bootz 加载kernel 流程分析
    Linux kernel 之 socket 创建过程分析
    Linux kernel 之 uart 驱动解析
    am335x 无屏实现开关机程序
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5554097.html
Copyright © 2020-2023  润新知