一本通 1774:大逃杀

\(\quad\) \(n\) 个点,\(n - 1\) 条边,显然就是一棵树了。题干说“可选择不获取资源”,但由于获取资源不需要时间,那显然必须要获取。
\(\quad\) 发现数据范围比较小,考虑多维 dp。设计如下:
\(\qquad\) \(\bullet\) 设 \(dp_{i,j,k}\) 表示从 \(i\) 出发,花费 \(k\) 单位时间到达 \(j\) 的最大收益。
\(\qquad\) \(\bullet\) \(dp_{i,j,k} = dp_{i,p,t} + dp_{p,j,k-t}\)
\(\quad\) 这样最多要转移 \(2.73 \times 10^{12}\) 次,显然超时。主要原因是状态设计得太过具体、暴力。
\(\qquad\) \(\bullet\) 设 \(f_{i,j}\) 表示花费 \(j\) 单位时间,从 \(i\) 出发,经过 \(i\) 的子树,最终返回 \(i\) 的最大收益;\(g_{i,j}\) 表示花费 \(j\) 单位时间,从 \(i\) 出发,最终到达 \(i\) 的子树的最大收益;\(h_{i,j}\) 表示花费 \(j\) 单位时间,从 \(i\) 的子树中出发,经过 \(i\),最终到达 \(i\) 的子树的最大收益。

\(\qquad\) \(\bullet\) 事实上,\(g_{i,j}\) 不但可以表示“花费 \(j\) 单位时间,从 \(i\) 出发,最终到达 \(i\) 的子树的最大收益”,还可以表示“花费 \(j\) 单位时间,从 \(i\) 的子树出发,最终到达 \(i\) 的最大收益”。
\(\quad\) 上述说明中的所有出发和到达都指:消灭了出发至到达路径上的所有敌人。个人感觉这道题还是相当复杂的,转移的具体描述和配图以后再补,可以先看代码试着理解。

#include <cstdio>

inline int read(void){
    static int res; res = 0; static char ch; ch = std::getchar();
    while(ch < '0' || ch > '9')
        ch = std::getchar();
    while(ch >= '0' && ch <= '9')
        res = res * 10 + ch - 48, ch = std::getchar();
    return res;
}

inline int max(const int& a, const int& b){
    return a > b ? a : b;
}

const int MAXN = 3e2 + 19;

struct Edge{
    int to, next, dist;
}edge[MAXN << 1];

int cnt, head[MAXN];

inline void add(int from, int to, int dist){
    edge[++cnt].to = to;
    edge[cnt].dist = dist;
    edge[cnt].next = head[from];
    head[from] = cnt;
}

int n, T;
int w[MAXN], t[MAXN];
int a, b, c;
int f[MAXN][MAXN], g[MAXN][MAXN], h[MAXN][MAXN];
int ans;

void dfs(int node, int fa){
    static int tmp[3];
    if(t[node] >= T)
        return;
    for(int i = head[node]; i; i = edge[i].next)
        if(edge[i].to != fa){
            dfs(edge[i].to, node);
            for(int j = T; j >= t[node]; --j){
                for(int k = j - edge[i].dist; k >= t[node]; --k){
                    tmp[0] = f[node][k], tmp[1] = g[node][k], tmp[2] = h[node][k];
                    int rest = j - k - edge[i].dist;
                    if(rest >= t[edge[i].to]){
                        g[node][j] = max(g[node][j], tmp[0] + g[edge[i].to][rest]);
                        h[node][j] = max(h[node][j], tmp[1] + g[edge[i].to][rest]);
                    }
                    rest -= edge[i].dist;
                    if(rest >= t[edge[i].to]){
                        g[node][j] = max(g[node][j], tmp[1] + f[edge[i].to][rest]);
                        f[node][j] = max(f[node][j], tmp[0] + f[edge[i].to][rest]);
                        h[node][j] = max(h[node][j], tmp[2] + f[edge[i].to][rest]);
                        h[node][j] = max(h[node][j], tmp[0] + h[edge[i].to][rest]);
                    }
                }
                ans = max(ans, h[node][j]);
            }
        }
}

int main(){
    n = read(), T = read();
    for(int i = 1; i <= n; ++i)
        w[i] = read();
    for(int i = 1; i <= n; ++i){
        t[i] = read();
        if(t[i] <= T)
            f[i][t[i]] = g[i][t[i]] = h[i][t[i]] = w[i];
    }
    for(int i = 1; i < n; ++i){
        a = read(), b = read(), c = read();
        add(a, b, c), add(b, a, c);
    }
    dfs(1, 0);
    std::printf("%d\n", ans);
    return 0;
}

\(\quad\) 其实只要出现了树形结构,就要试着考虑树形 dp,不要再去想奇奇怪怪的转移方程了。树形 dp 的特点:
\(\qquad\) \(\bullet\) 状态与单个节点有关,每个节点的状态都一定可以由子节点转移。
\(\qquad\) \(\bullet\) 转移与 dfs 结合。
\(\quad\) 在树形 dp 中,如果给定的图的边都是自上而下的,一定可以连有向边,最上面的点为根。反之,连无向边,随意选取根节点(有时不选 \(1\) 当根会被卡)。
本文系参考 1773:大逃杀 而成。

原文地址:https://www.cnblogs.com/natsuka/p/12298470.html

时间: 2024-11-09 02:07:43

一本通 1774:大逃杀的相关文章

1774:大逃杀

1774:大逃杀        时间限制: 1000 ms         内存限制: 262144 KB    提交数: 49     通过数: 19    [题目描述]        将地图上的所有地点标号为1到n,地图中有n-1        条双向道路连接这些点,通过一条双向道路需要一定时间,保证从任意一个点可以通过道路到达地图上的所有点.        有些点上可能有资源,到达一个有资源的点后,可以获取资源来增加 wi的武力值.        资源被获取后就会消失,获取资源不需要时间.

杀出一个未来!即刻开始微信大逃杀

有多少人每天零散时间.睡前的习惯,都是打开微信,看看朋友圈里都更新了哪些内容?随着微信成为社交通信应用里的巨无霸,它已经紧紧地将我们的社会关系链揉捏在一起,在这张大网上,我们无所遁形.从开始的新鲜,到后来时间被大量"谋杀",再到关系的混乱,越来越多的人在享受微信带来的便利时,开始在思索微信的弊端是否能与便利画上等号. 于是,一场反主流的"微信大逃杀"正在迅速开始波及.而这场大逃杀并没有明显的发起者,最多只是能从群体上去说--正是那些被微信私人.工作.亲友.面膜挤压的

“大逃杀”这么火,为何国内“绝地求生”都靠手游撑面子?

2017年的现象级游戏<绝地求生:大逃杀>(简称<绝地求生>)席卷全球,该游戏的创意总监近日表示,其销量突破了2000万份. <绝地求生>是一款玩法直白简洁的"大逃杀"类游戏,每局游戏有100名玩家参与,玩家被投放到孤岛上进行对抗,最终生存的玩家仅有一人,幸存玩家屏幕上会出现一行字:"Winner Winner,Chicken Dinner",直接翻译过来就是"大吉大利,晚上吃鸡",因此这类游戏也被称作&quo

绝地求生大逃杀BE启动失败,应用程序无法正常启动

今日更新绝地求生大逃杀后部分客户反馈绝地求生点击启动提示BE安装,应用程序无法启动 问题原因:经过排查发现,客户开启过超级工作站运行过游戏,在系统镜像包中保留了旧版的BE服务,致使新版BE无法安装,冲突报错. 解决方法:因此,优先在启动前需要在系统中结束删除旧版BE服务.可通过开超级运行sc delete beservice 命令来删除旧版BE 启动后正常.(开机批处理亦可) 建议:在开启超级工作站后不要运行任何游戏,因为游戏在运行过程可能会安装一些游戏需要的程序,可能会与更新后的该程序或者是其

《绝地求生大逃杀》BE错误怎么办 BE服务未正常运行及安装失败解决方法

<绝地求生大逃杀>BattlEye Launcher是游戏的反作弊程序,也是启动过程中做容易出现错误的,今天小编带来"爆锤吧务"分享的<绝地求生大逃杀>BE服务未正常运行及安装失败解决方法,有此烦恼的玩家赶紧来看吧. 在启动游戏之前切换成英文输入法,美式键盘. DLL文件的各种问题 dxgi.dll,d3d11.dll,uxtheme.dll,JiXunlsp641.4.dll,MSSPIREX64.DLL,NetDogDll64.dll等等. 以.dll结尾的

绝地求生大逃杀,改配置

提取效果设置配置文件 通过Procmon工具分析,绝地求生大逃杀效果设置的配置文件为 "C:\Users\Administrator\AppData\Local\TslGame\Saved\Config\WindowsNoEditor\GameUserSettings.ini",设置好网吧需要的游戏效果后将"TslGame"文件夹提取出来即可(只需保留GameUserSettings.ini). 3.应用到所有客户机 在服务器上挂载客户机镜像(如果不知道怎么挂载镜像

绝地求生大逃杀裸连教程

使用软件PingInfoView,把最下面的服务器IP都复制进去,哪个最稳定最快 就用哪个 软件下载地址 ftp://hhdown:[email protected]/download/HA-PinginfoViewChs-1.55.rar 下面是我用 的速度快的IP 54.230.141.207 打开文件夹目录 C:\Windows\System32\drivers\etc里的hosts的文件,右键以管理员身份用记事本打开. 添加以下记录 #54.182.1.137 front.battleg

[51nod2982] 大逃杀

问题描述 α?76星人入侵地球,尽管英勇的地球卫士们奋勇杀敌,但战火依然烧到了地球本球上,为了维护人类的利益,联合国决定建立m个避难所,第i个避难所能容纳ci个人,坐标为(pi,qi).现在地球上还残余着n个国家,第i个国家有bi个人,坐标为(xi,yi),现在联合国给出了一个初步的疏散方案,即一个n*m的矩阵a,其中ai,j表示第i个国家去第j个避难所的人数(\(b_i=\sum_{1\le j\le m}a_{i,j}\)且\(\sum_{1\le i\le n}a_{i,j}\le c_j

最高机密 曝中国目前最尖端的两大秘密杀器

北京时间12日消息,据国外媒体报道,美国航空航天局(NASA)的一项新研究发现,过去数十年来南极海冰的增加并不足以抵消加速减少的北极海冰.整合两极的数据可以看到,全球海冰面积正以平均每年约35000平方公里的速度减少,换句话说,每年减少的海冰面积比美国马里兰州还大将北极海冰的减少量与南极海冰增加量进行整合之后,可以发现自1979年以来,全球海冰面积正以平均每年约35000平方公里的速度减少,换句话说,每年减少的海冰面积比美国马里兰州还大. "尽管去年九月,南极海冰面积达到了新的最大记录,但全球海