P2465 [SDOI2008]山贼集团 dp
这个题是一道树形dp+状压dp二合一,先预处理每种组合会有什么额外的费用,然后在树上dp就行了。
题干:
题目描述某山贼集团在绿荫村拥有强大的势力,整个绿荫村由N个连通的小村落组成,并且保证对于每两个小村落有且仅有一条简单路径相连。小村落用阿拉伯数字编号为1,2,3,4,…,n,山贼集团的总部设在编号为1的小村落中。山贼集团除了老大坐镇总部以外,其他的P个部门希望在村落的其他地方建立分部。P个分部可以在同一个小村落中建设,也可以分别建设在不同的小村落中。每个分部到总部的路径称为这个部门的管辖范围,于是这P个分部的管辖范围可能重叠,或者完全相同。在不同的村落建设不同的分部需要花费不同的费用。每个部门可能对他的管辖范围内的小村落收取保护费,但是不同的分部如果对同一小村落同时收取保护费,他们之间可能发生矛盾,从而损失一部分的利益,他们也可能相互合作,从而获取更多的利益。现在请你编写一个程序,确定P个分部的位置,使得山贼集团能够获得最大的收益。 输入输出格式 输入格式:输入文件第一行包含一个整数N和P,表示绿荫村小村落的数量以及山贼集团的部门数量。接下来N-1行每行包含两个整数X和Y,表示编号为X的村落与编号为Y的村落之间有一条道路相连。(1<=X,Y<=N)接下来N行,每行P个正整数,第i行第j个数表示在第i个村落建设第j个部门的分部的花费Aij。然后有一个正整数T,表示下面有T行关于山贼集团的分部门相互影响的代价。(0<=T<=2p)最后有T行,每行最开始有一个数V,如果V为正,表示会获得额外的收益,如果V为负,则表示会损失一定的收益。然后有一个正整数C,表示本描述涉及的分部的数量,接下来有C个数,Xi,为分部门的编号(Xi不能相同)。表示如果C个分部Xi同时管辖某个小村落(可能同时存在其他分部也管辖这个小村落),可能获得的额外收益或者损失的收益为的|V|。T行中可能存在一些相同的Xi集合,表示同时存在几种收益或者损失。输出格式:输出文件要求第一行包含一个数Ans,表示山贼集团设置所有分部后能够获得的最大收益。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) {char c;bool op = 0;while(c = getchar(), c < '0' || c > '9')if(c == '-') op = 1;x = c - '0';while(c = getchar(), c >= '0' && c <= '9')x = x * 10 + c - '0';if(op) x = -x; } template <class T> void write(T x) {if(x < 0) putchar('-'), x = -x;if(x >= 10) write(x / 10);putchar('0' + x % 10); } const int N = 110; int lst[N],len = 0; int dp[N][4200]; int val[4200]; struct node {int l,r,nxt; }a[N << 1]; int n,m; void add(int x,int y) {a[++len].l = x;a[len].r = y;a[len].nxt = lst[x];lst[x] = len; } void initdp() {int cost[N][13];duke(i,1,n){duke(j,0,m - 1){read(cost[i][j]);}dp[i][0] = 0;for(int j = 1;j < (1 << m);++j){int lowbit = j & (-j);int lowid = (log(lowbit) + 0.001) / log(2);dp[i][j] = dp[i][j ^ lowbit] - cost[i][lowid];}} } void calval(int x) {duke(i,1,x){int v,cnt,s = 0;read(v);read(cnt);duke(j,1,cnt){int mem;read(mem);s |= (1 << (mem - 1));}int maxm = (1 << m) - 1;val[s] += v;int tmp = s ^ maxm;for(int j = tmp;j;j = (j - 1) & tmp){val[(s | j)] += v;}} } void dfs(int now,int fa) {for(int k = lst[now];k;k = a[k].nxt){int y = a[k].r;if(y != fa){dfs(y,now);for(int j = (1 << m) - 1;j;j--){for(int i = j;i;i = (i - 1) & j){dp[now][j] = max(dp[now][j],dp[now][j ^ i] + dp[y][i]);}}}}for(int i = (1 << m) - 1;i;i--){dp[now][i] += val[i];} } int main() {read(n);read(m);duke(i,1,n - 1){int x,y;read(x);read(y);add(x,y);add(y,x);}initdp();int t;read(t); // cout<<t<<endl; calval(t);dfs(1,0);printf("%d\n",dp[1][(1 << m) - 1]);return 0; }
转载于:https://www.cnblogs.com/DukeLv/p/10434434.html
P2465 [SDOI2008]山贼集团 dp相关推荐
- 洛咕 P2465 [SDOI2008]山贼集团
裸的状压dp. 设f[i][j]表示在i字数内放j集合的分部,直接sb转移. // luogu-judger-enable-o2 #include<bits/stdc++.h> #defi ...
- [SDOI2008]山贼集团【树上背包+状压】
洛谷P2465 SOL 比较经典的一类树上背包问题套一个子集状压枚举. 注意到代价的计算与所选的点的集合有关,如果我们要统计代价需要状压记录点集,而数据范围非常配合的给了P≤12P\le12P≤12, ...
- 【学术篇】SDOI2008 山贼集团
今天一月一号.. 突然想安利一波我的中二的2017总结- 传送门1:codevs 传送门2:luogu 时限5s和1s的区别(你没看我传送门都给的大牛分站了) 现在不仅线筛.. 有负数的快读都打不对了 ...
- 【[SDOI2008]山贼集团】
非常好的一道题 树上的状压\(dp\) 根据数据范围我们就能知道这是一道需要状压的题目 所以状态就是\(dp[i][S]\)表示在以\(i\)为根的子树里,选择的状态为\(S\)的最大收益 这个收益只 ...
- 【SDOI2008】山贼集团
本题的模型是树形状态压缩的动态规划. 首先考虑简单的题目模型:对于任何形态的有根树 T,都可以建立其等效二叉树 T',若在原树 T 中,结点 x 有儿子c1,c2,c3,-,ck c1,c2,c3,- ...
- [FROM WOJ]#2040 山贼集团
#2040 山贼集团 SDOI2008 题面 某山贼集团在绿荫村拥有强大的势力,整个绿荫村由N个连通的小村落组成,并且保证对于每两个小村落有且仅有一条简单路径相连.小村落用阿拉伯数字编号为1,2,3, ...
- 山贼集团 (group)
山贼集团 (group) 题目描述 某山贼集团在绿荫村拥有强大的势力,整个绿荫村由N个连通的小村落组成,并且保证对于每两个小村落有且仅有一条简单路径相连.小村落用阿拉伯数字编号为1,2,3,4,-,n ...
- 【Luogu】P2465山贼集团(树形状压DP)
题目链接 写了个70分暴力还挂了,第一遍提交只拿了十分--海星 首先建虚拟节点多叉树转成二叉,然后子集枚举DP 设g[x][i]是以x为根的子树内山贼集合i,x啥都不选也没贡献的时候的最大价值 f[x ...
- 「SDOI 2008」山贼集团
传送门 problem 给定一棵 nnn 个点且根为 111 的树,有 ppp 个部门,每个部门会占据一个点,占据点会有代价,不同部门可以占据同一个点,每个部门的管辖范围是 111 到他占据点的链上的 ...
最新文章
- 滴滴开源在2019:十大重点项目盘点,DoKit客户端研发助手首破1万Star
- 002_SpringBoot整合Servlet
- 七、linux驱动注册
- php 频繁dom和 文件,性能优化之为什么不要频繁操作DOM
- [vue] vue使用v-for遍历对象时,是按什么顺序遍历的?如何保证顺序?
- 代码审查:程序员内炼之道
- 3-17Pytorch与线性代数运算
- ARM中R0-R15寄存器的作用
- fatal: unable to access ‘https://github.com/abseil/abseil-cpp.git/‘: Failed connect to github.com:44
- 全面了解风控数据体系
- 计算机excel表格公式教程,职称计算机Excel教程:显示公式的方法
- Cura工程环境配置教程
- 批量下载ERA5数据(Python+IDM)
- 知云文献,Endnote简易使用指南
- 跳槽重回前公司?当初的离职原因没解决,早晚还得辞职
- OpenGL显示文字--显示英文
- ESP8266 下载报错please check partition type 6 addr:3fd000 len:3000
- python三大器,Python 入门之 Python三大器 之 生成器
- ITON RW6852-50S WIFI6模组
- 3dmax第二次安装遇到的问题及解决方案