HYSBZ - 1017 魔兽地图【树形DP依赖性背包】

HYSBZ - 1017

Description

DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars。DotR里面的英雄只有一个属性——力量。他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力量值之和。装备分为基本装备和高级装备两种。基本装备可以直接从商店里面用金币购买,而高级装备需要用基本装备或者较低级的高级装备来合成,合成不需要附加的金币。装备的合成路线可以用一棵树来表示。比如,Sange and Yasha的合成需要Sange, Yasha和Sange and Yasha Recipe Scroll三样物品。其中Sange又要用Ogre Axe, Belt of Giant Strength 和 Sange Recipe Scroll合成。每件基本装备都有数量限制,这限制了你不能无限制地合成某些性价比很高的装备。现在,英雄Spectre有M个金币,他想用这些钱购买装备使自己的力量值尽量高。你能帮帮他吗?他会教你魔法Haunt(幽灵附体)作为回报的。

Input

输入文件第一行包含两个整数,N (1 <= n <= 51) 和 m (0 <= m <= 2,000)。分别表示装备的种类数和金币数。装备用1到N的整数编号。接下来的N行,按照装备1到装备n的顺序,每行描述一种装备。每一行的第一个正整数表示这个装备贡献的力量值。接下来的非空字符表示这种装备是基本装备还是高级装备,A表示高级装备,B表示基本装备。如果是基本装备,紧接着的两个正整数分别表示它的单价(单位为金币)和数量限制(不超过100)。如果是高级装备,后面紧跟着一个正整数C,表示这个高级装备需要C种低级装备。后面的2C个数,依次描述某个低级装备的种类和需要的个数。

Output

第一行包含一个整数S,表示最多可以提升多少点力量值。

Sample Input

10 59
5 A 3 6 1 9 2 10 1
1 B 5 3
1 B 4 3
1 B 2 3
8 A 3 2 1 3 1 7 1
1 B 5 3
5 B 3 3
15 A 3 1 1 5 1 4 1
1 B 3 5
1 B 4 3

Sample Output

33

题意:见上文
分析:树形DP。 dp[i][j][k]表示以第i种物品为根的子树花费j,向上层提供k个i所得到的的最大贡献值。
    对于每个节点,枚举合成1至n个物品的最大能力值,背包问题。
ACcode
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=2020;
const int M=58;
int dp[M][105][N],pre[M],num[M],val[M],f[M][N];
int n,m;
bool fa[M],flag;
struct edge
{
    int to,need;
    edge(int x,int y)
    {
        to=x;
        need=y;
    }
};
vector<edge> g[M];
void dfs(int x)
{
    if(g[x].size()==0)
    {   //cout<<"  *"<<x<<endl;
        num[x]=min(num[x],m/pre[x]);
        for(int i=0;i<=num[x];i++)
            for(int j=i;j<=num[x];j++)
            dp[x][i][j*pre[x]]=(j-i)*val[x];
            return ;
    }
    num[x]=INF;
    for(int i=0;i<g[x].size();i++)
    {
        int y=g[x][i].to,z=g[x][i].need;
        dfs(y);
        num[x]=min(num[x],num[y]/z);
        pre[x]+=(z*pre[y]);
    }
    num[x]=min(num[x],m/pre[x]);
    memset(f,-0x3f3f3f3f,sizeof(f));
    f[0][0]=0;  //背包
    for(int c=num[x];c>=0;c--)
    {
        for(int i=0;i<g[x].size();i++)
        {
            int y=g[x][i].to,z=g[x][i].need;
            for(int v=0;v<=m;v++)
                for(int k=v;k>=0;k--)
                f[i+1][v]=max(f[i+1][v],f[i][v-k]+dp[y][c*z][k]);
        }
        int len=g[x].size();
        for(int i=0;i<=c;i++)
            for(int v=0;v<=m;v++)
            dp[x][i][v]=max(dp[x][i][v],(c-i)*val[x]+f[len][v]);
    }
    return ;
}
void init()
{
    memset(dp,-0x3f3f3f3f,sizeof(dp));
    memset(fa,false,sizeof(fa));
    memset(pre,0,sizeof(pre));
    for(int i=1;i<=n;i++)
        g[i].clear();
}
char ch[2];
int main()
{
    int ans;
   while(scanf("%d%d",&n,&m)!=EOF)
   {
       init();
       ans=-INF;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%s",&val[i],ch);
            if(ch[0]=='A')
            {
                int tot;
                scanf("%d",&tot);
                while(tot--)
                {
                    int to,vall;
                    scanf("%d%d",&to,&vall);
                    fa[to]=true;
                    g[i].push_back(edge(to,vall));
                }
            }
            else scanf("%d%d",&pre[i],&num[i]);
        }
       flag=false;
       for(int i=1;i<=n;i++)if(fa[i])flag=true;
       if(flag)
       {
           for(int i=1;i<=n;i++)
           {
               if(fa[i])continue;
               dfs(i);
               for(int j=0;j<=num[i];j++)
                for(int k=0;k<=m;k++)
                ans=max(ans,dp[i][j][k]);
           }
       }
       else
       {
           memset(f,0,sizeof(f));
           for(int i=1;i<=n;i++)
           {
               for(int j=0;j<=num[i];j++)
               for(int v=m;v>=j*pre[i];v--)
               {
                f[i][v]=max(f[i][v],f[i-1][v-j*pre[i]]+j*val[i]);
               }
           }
           for(int v=0;v<=m;v++)
            ans=max(ans,f[n][v]);
       }
       printf("%d\n",ans);
   }
   return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
功能最强大的Jass编辑器更新 1.4.3.3 -> 1.4.3.4[!] 修正了当字符串或注释中存在括号时括号提示的显示错误问题;[!] plugin(插件)菜单不再可以使用任意热键;[!] 修正了Shortcut Manager的程序运行期间内存泄露问题;[!] 修正了打开某些地图文件时Global List中Triggers可能产生严重错误的问题;[+] 增加了提示无对应的括号的提示(该功能默认关闭);[+] 保存脚本文件到地图文件中时自动删除"(attributes)"文件;[+] 在config.exe中增加了关联地图类型文件(*.W3M, *.W3X)功能(使用该功能时请选择“否”,否则将覆盖掉原来使用WE打开的关联方式);[+] Shortcut Manager的热键选择列表中去除plugin菜单已使用的热键; 将UTF8<->ASC功能移动到Format All/Selected Text菜单下; 提高了文件较长时的一些相关功能的效率。文件说明JassShopPro.exe - 主程序config.exe - 设置程序。许多JSP有许多强大的功能需要调用该文件来设定MpqLib.dll - 用于直接读取地图中的jass文件的动态链接库(Thx to Soar)CHS.lng - 简体中文语言包。建议每次更新都覆盖掉default.tmt - 模板文件。这是一个文本文件,可以根据该文件内容(挺容易懂的)设计自定义的模板菜单,支持快捷键和一些控制命令。可以通过config.exe定义自己的模板菜单文件common.j, blizzard.j, common.ai - 目前为1.18的API文件,主程序至少需要common.j文件pjass.exe - 用于语法检查,无此文件,主程序中的语法检查将不可用jsp.ini - JassShopPro.exe会自动创建该文件,用于保存设置,无此文件时config.exe不可用。当首次运行JassShopPro的时候,如果没有找到这个文件,程序会自动搜索并提问是否使用语言包(语言包有特殊的设定,如果是某些英文版改的中文版xp的或者新加坡中文版之类,不会自动提问CHS.lng)功能 语法高亮 根据jass2语言定义了十几种字体,可以通过config.exe自己设定字体颜色、风格,以及高亮规则 智能大小写转换 可自动转换大小写,并能自动判断是否进行大小写转换,例如输入 “location”,此时如果再输入“(”,程序将认为它是函数,自动转换成“Location(”,否则认为是类型,不进行大小写转换 快速函数搜索 可以方便快捷的查找API函数、常量、变量、类型。可以选择是否从名称第一个字母开始匹配,是否注意大小写,该函数的返回类型或变量、常量的类型。搜索按钮将自动在所有函数/变量常量/类型中查找。按回车或者空格会将当前词汇添加到下拉菜单中。单击其中条目,下面的代码框中将显示源代码,双击搜索列表中项目,将自动插入代码 标准的MDI(多文档界面)操作 Ctrl+F4关闭一个文档,Ctrl+Tab切换文档 功能强大的搜索功能 有丰富的选项,在主界面编辑时会智能填入搜索内容。如选中代码不含有换行符,搜索对话框中将自动填入选中的文本,超过一行则会自动将搜索范围变为 Selected Text (选中文本) 书签功能 每个编辑中的文本可以定义10个书签 当前代码结构 左侧的列表会显示全部的全局变量、函数、全局Trigger。红色的变量代表常量,红色的函数代表常函数,红色的Trigger代表缺乏全局变量声明的T。目前Trigger列表只是列出来,没有任何实际功能。对于变量和函数,左键单击在代码框中显示代码,右键单击跳转到声明位置,双鞑迦耄孛旖菁麱2 )会在整个编辑文本中改名 强大的模板引擎 具体可以参照Default.tmt文件,可以自定义类别,自定义快捷键,做一些比较复杂的功能 语法检查 该功能需要pjass.exe文件。可以在检查结果中双击条目跳转到出错位置 测试地图 现在程序已经支持直接打开地图文件中的war3map.j或者scripts\war3map.j文件,或者直接储存到地图文件中。如果正在编辑的是地图文件,可立刻使用WE的标准操作快捷键Ctrl+F9进行地图测试 插入颜色 可以直观的选择颜色,然后转换成jass的颜色代码插入到文本中 强大的文本缩进 可通过config.exe设置tab键的宽度,编辑代码时也会根据关键词进行缩进。菜单中提供了缩进、去除缩进、增加缩进功能,自动根据是否选中文本对选中代码或者全文进行缩进处理,方便阅读 与WE通信 可以直接与WE的文本编辑框通信,相互复制代码 UTF-8 <-> ASC 人性化的操作 主程序支持参数,可以通过config.exe在注册表中注册文件类型,从而双击打开相关类型文件。如果已经有一个JassShopPro在运行中,再次双击注册为用JSP打开的类型的文件时,将在已启动的文档中打开文件。同样,支持拖放操作,可以直接将文件拖到窗口中打开 自动完成功能 输入“set ”,将自动显示本地变量与全部全局变量;输入“call ”,则会自动显示当前代码前面的全部函数。输入一个有效的函数名称并按“(”时,将显示该函数参数的提示(或者按F1) 丰富的快捷键 大多数有用的功能都提供了快捷键。 Ctrl+鼠标左键单击(F2):如果大小写不正确,会自动转换大小写。如果被点中的是当前文档的全局变量、常量或者函数,则会自动跳转到声明位置 双击:可在代码框中得到相关的源代码 压缩代码 可以进行一些简单的代码压缩处理,可以处理:去除注释,压缩全局变量、常量名称,压缩函数名称,去除无用回车,去除缩进等 自定义菜单快捷键 主程序中的Shortcut Manager可以方便帮助您设置菜单中的快捷键,方便需要 plug-in 支持插件程序,可以通过config.exe方便的管理已安装的插件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值