[JSOI2008]魔兽地图

树上背包

题目传送门

首先,有没有哪位dalao 愿意告诉我为什么合成高级装备不需要附加金币,,

好吧,这个不重要

明确表示装备合成路线可以用一棵树来表示。一颗?傻乎乎的在下之前每次就只dp一棵树,不出意外的WA了,,在看几遍,好嘛,好像是个森林啊(泪奔)

最容易想到的dp[x][i][j]是第x件买了i个,花了j元的最高力量。但是,,这样好像就成为不可做题了(欢迎各路dalao打脸,反正不是我说的[手动滑稽](偷偷扔出FYJ挡枪)),那么换一种思路,还是dp[x][i][j],但表示的是第x件装备,用i件合成上级装备(即至少买了i件),花费j元的力量。如果i是基础装备,转移方程就直接出来了:d[x][i][j*cost[x]]=power[x]*(j-i)。

如果是高级装备呢?

那就枚举它买多少件,以及它的子装备买多少件,直接暴力转移,n^2*times^2。看看时限,3s,完全不方

在下代码比较丑,求各位不要介意

#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iostream>
#define ll int
#define re register
#define inf 0x3f3f3f3f
#define inl inline
#define sqr(x) (x*x)
//#define eps 1e-8
#define debug printf("debug\n");
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
using namespace std;
//const ll mod;
const ll MAXN=3e5+10;
inl ll read() {
    re ll x = 0; re int f = 1;
    char ch = getchar();
    while(ch<‘0‘||ch>‘9‘) { if(ch== ‘-‘ ) f = -1; ch = getchar(); }
    while(ch>=‘0‘&&ch<=‘9‘) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x * f;
}
inl char readc() {
    char ch=getchar();
    while((‘z‘<ch||ch<‘a‘)&&(‘Z‘<ch||ch<‘A‘)) ch=getchar();
    return ch;
}
inl void write(re ll x){
    if(x>=10)write(x/10);
    putchar(x%10+‘0‘);
}
inl void writeln(re ll x){
    if(x<0) {x=-x;putchar(‘-‘);}
    write(x); puts("");
}
inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;}
inl void FR() {
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
}
inl void FC() {
    fclose(stdin);
    fclose(stdout);
}
struct Node {
    ll u,v,w,nxt;
}e[20005<<1];
ll cnt,head[60],ssw[60],g[20005],cost[60],times[60];
bool fl[60],in[60],vis[60];
ll ans[20005];
inl void adde(ll u,ll v,ll w) {
    e[++cnt].u=u;e[cnt].v=v;e[cnt].w=w;
    e[cnt].nxt=head[u];head[u]=cnt;
}
ll d[60][105][2005],n,m;
void dp(ll x) {
    if(vis[x]) return ;vis[x]=1;
    if(!fl[x]) {//基础装备
        times[x]=min(times[x],m/cost[x]);
        for(re ll i=times[x];~i;i--) {
            for(re ll j=i;j<=times[x];j++) {
                d[x][i][j*cost[x]]=ssw[x]*(j-i);
            }
        }
        return ;
    }
    for(re ll h=head[x];h;h=e[h].nxt) {
        dp(e[h].v);cost[x]+=e[h].w*cost[e[h].v];
        times[x]=min(times[x],times[e[h].v]/e[h].w);
    }
    times[x]=min(times[x],m/cost[x]);
    for(re ll i=times[x];~i;i--) {
        for(re ll j=1;j<=m;j++) g[j]=-inf;g[0]=0;
        for(re ll h=head[x];h;h=e[h].nxt) {
            for(re ll k=m;~k;k--) {
                re ll sst=-inf;
                for(re ll l=0;l<=k;l++) {sst=max(sst,g[k-l]+d[e[h].v][i*e[h].w][l]);}
                g[k]=sst;//花k元能到的最高力量
            }
        }
        for(re ll j=0;j<=i;j++) {
            for(re ll l=0;l<=m;l++) {
                d[x][j][l]=max(d[x][j][l],g[l]+ssw[x]*(i-j));
            }
        }
    }
}
int main(){
//    FR();
    n=read(),m=read();
    memset(times,inf,sizeof(times));
    memset(d,-inf,sizeof(d));
    for(re ll i=1;i<=n;i++) {
        ssw[i]=read();
        char sj[3];scanf("%s",sj);
        if(sj[0]==‘A‘) {
            fl[i]=1;re ll c=read();
            for(re ll j=1;j<=c;j++) {
                re ll sx=read(),xs=read();
                if(!in[sx]) in[sx]=1;
                adde(i,sx,xs);
            }
        }
        else if(sj[0]==‘B‘) {
            fl[i]=0;cost[i]=read();
            times[i]=read();
        }
        else puts("RE");
    }
    for(re ll i=1;i<=n;i++) {
        if(!in[i]) {//被坑无数次
            dp(i);
            for(re ll j=m;~j;j--) {
                for(re ll k=0;k<=j;k++) {
                    ans[j]=max(ans[j],ans[j-k]+d[i][0][k]);
                }
            }
        }
    }
    writeln(ans[m]);
//    FC();
    return 0;
}

原文地址:https://www.cnblogs.com/20020723YJX/p/9348020.html

时间: 2024-08-04 08:56:44

[JSOI2008]魔兽地图的相关文章

BZOJ [JSOI2008]魔兽地图DotR

1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1243  Solved: 532[Submit][Status][Discuss] Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性——力

【BZOJ 1017】 [JSOI2008]魔兽地图DotR

1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MB Submit: 1069  Solved: 433 [Submit][Status] Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性--力量.他们需要购

bzoj 1017[JSOI2008]魔兽地图DotR - 树形dp

1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MB Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性--力量.他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄

[BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)

Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性——力量.他们需要购买装备来提升自己的 力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力 量值之和.装备分为基本装备和高级装备两种.基本装备可以直接从商店里面用金币购买,而高级装备需要用

[luogu4037 JSOI2008] 魔兽地图 (树形dp)

传送门 Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars. DotR里面的英雄只有一个属性--力量.他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力量值之和.装备分为基本装备和高级装备两种.基本装备可以直接从商店里面用金币购买,而高级装备

[JSOI2008]魔兽地图(树形dp)

DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars. DotR里面的英雄只有一个属性--力量.他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力量值之和.装备分为基本装备和高级装备两种.基本装备可以直接从商店里面用金币购买,而高级装备需要用基本装备或者较低级的高级装

BZOJ1017: [JSOI2008]魔兽地图DotR

传送门 设$f[i][j][k]$表示对于第$i$个点,向父节点贡献$j$个已合成的装备,花费了$k$的代价,最多获得的力量值. 单纯的$f[i][j][k]$是很难转移的,主要原因是无法维护和其他儿子的关系.所以对于每个节点再搞一个$g[i][j]$表示当前点的前$i$个儿子花费为$k$可以获得的最大的力量值. 然后肯定要先更新$g[][]$再以$g[][]$来更新$f[][][]$. 列出$g[i][j]$的状态转移方程就是: $g[cnt][k]=max \{ f[son][tol \ti

bzoj 1017 : [JSOI2008]魔兽地图DotR

比较难想的的一道树形dp. 看到这道题正常的思路应该是$f[i][j][k]$表示i这棵子树里买了j个i物品花费为k的最大收益. 但如果直接这么定义的话转移复杂度会很高,需要枚举j,枚举孩子,枚举k,枚举孩子的花费,还要枚举每个孩子各买了多少件. 想办法把最后一个循环去掉. 重新定义状态$f[i][j][k]$表示表示i这棵子树里至少买了j个i物品花费为k的最大收益. 每次枚举完物品数量后加上这么一句 if(i!=l[x])f[x][i][j]=max(f[x][i][j],f[x][i+1][

[JSOI2008][BZOJ1017] 魔兽地图DotR|树形动规

1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1254  Solved: 537[Submit][Status][Discuss] Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性——力