【BZOJ 4007】[JLOI2015]战争调度 DP+搜索+状压
又是一道思路清新的小清晰。
观察题目,如果我们确定了平民或者贵族的任意一方,我们便可以贪心的求出另一方,至此20分;我们发现层数十分小,那么我们就也是状压层数,用lca转移,线性dp,至此50分(好像数据很水这么打能A);至今我们没有用到他是一棵完全二叉树,那么我们发现如果进行树dp,也就是说从子节点转移到父节点,f[i][j],以i为根的子树里的平民有j个参战贡献最大值,我们需要确定平民的请况而且有不能状压,但是结合我们上次得出的结论,我们发现如果我们dp状态的意义为,在确定由此节点到root的所有节点的状态时,以i为根的子树里的平民有j个参战贡献最大值,我们就可以不用知道平民的情况了,就是f[i][j][k],那么我们就可以合并上去了,然而我们发现这样不仅TLE而且MLE,但是如果我们k那一维通过枚举而实现呢,我们就可以即时转移而去掉最后一维,而且丢掉许多无效状态,然而我们发现k他从最底层到最高层呈现指数递减,我们可以兴奋一下然后认真考虑时间复杂度了:对于每一个出口也就是叶子节点我们最多出去2^10次并且每次算贡献O(10),于是O(10*2^20),然后每次合并——在根处2^9*2^9*1,往下走一层需要合并的点数乘2^2,合并大小除2,于是总的为层数乘点数平方即O(10*2^20)。于是总时间复杂度O(10*2^20)。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls (pos<<1)
#define rs ((pos<<1)|1)
using std::max;
const int N=(<<)+;
int f[N][N],tw[N][],tg[N][],w[N][N],g[N][N];
int n,m,len,bin[];
void read_pre(){
scanf("%d%d",&n,&m),len=<<(n-);
for(int i=;i<=len;++i)
for(int j=;j<n;++j)
scanf("%d",&tw[i][j]);
for(int i=;i<=len;++i)
for(int j=;j<n;++j)
scanf("%d",&tg[i][j]);
for(int i=;i<=len;++i)
for(int j=;j<len;++j)
for(int k=;k<n;++k)
(j&(<<(k-)))?w[i+len-][j]+=tw[i][k]:g[i+len-][j]+=tg[i][k];
bin[n-]=;
for(int i=n-;i>;--i)bin[i]=bin[i+]<<;
}
void dfs(int pos,int deep,int state){
if(deep==n){
f[pos][]=g[pos][state],f[pos][]=w[pos][state];
return;
}
memset(f[pos],,sizeof(f[pos]));
dfs(ls,deep+,state|bin[deep]),
dfs(rs,deep+,state|bin[deep]);
for(int i=;i<=bin[deep];++i)
for(int j=;j<=bin[deep];++j)
f[pos][i+j]=max(f[pos][i+j],f[ls][i]+f[rs][j]);
dfs(ls,deep+,state),
dfs(rs,deep+,state);
for(int i=;i<=bin[deep];++i)
for(int j=;j<=bin[deep];++j)
f[pos][i+j]=max(f[pos][i+j],f[ls][i]+f[rs][j]);
}
void work_print(){
dfs(,,);int ans=;
for(int i=;i<=m;++i)
ans=max(ans,f[][i]);
printf("%d",ans);
}
int main(){
read_pre();
work_print();
return ;
}
【BZOJ 4007】[JLOI2015]战争调度 DP+搜索+状压的更多相关文章
- BZOJ 1076: [SCOI2008]奖励关 [DP 期望 状压]
传送门 题意:$n$种宝物,出现$k$次每次一种,每种宝物有价值和吃掉它之前必须要吃掉的宝物的集合,求采取最优策略的期望最大价值 1<=k<=100,1<=n<=15,分值为[ ...
- [BZOJ4007][JLOI2015]战争调度(DP+主定理)
第一眼DP,发现不可做,第二眼就只能$O(2^{1024})$暴搜了. 重新审视一下这个DP,f[x][i]表示在x的祖先已经全部染色之后,x的子树中共有i个参战平民的最大贡献. 设k为总结点数,对于 ...
- 【BZOJ4007】[JLOI2015]战争调度(动态规划)
[BZOJ4007][JLOI2015]战争调度(动态规划) 题面 BZOJ 洛谷 题解 神仙题,我是做不来. 一个想法是设\(f[i][j]\)表示当前考虑到\(i\)节点,其子树内有\(j\)个人 ...
- [JLOI2015]战争调度
[JLOI2015]战争调度 题目 解题报告 考试打了个枚举的暴力,骗了20= = $qsy$大佬的$DP$: 其实就是枚举= =,只不过枚举的比较强= = #include<iostream& ...
- 【题解】JLOI2015战争调度
搜索+状压+DP. 注意到一个性质:考虑一棵以x为根的子树,在x到原树的根的路径上的点如果都已经确定了方案,那么x的左右儿子的决策就彼此独立,互不影响了.所以我们考虑状压一条路径上每一层节点的状态,求 ...
- Codeforces Gym 191033 E. Explosion Exploit (记忆化搜索+状压)
E. Explosion Exploit time limit per test 2.0 s memory limit per test 256 MB input standard input out ...
- 树形DP和状压DP和背包DP
树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...
- dp乱写1:状态压缩dp(状压dp)炮兵阵地
https://www.luogu.org/problem/show?pid=2704 题意: 炮兵在地图上的摆放位子只能在平地('P') 炮兵可以攻击上下左右各两格的格子: 而高原('H')上炮兵能 ...
- poj2411 Mondriaan's Dream (轮廓线dp、状压dp)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17203 Accepted: 991 ...
随机推荐
- android发布帖子类技术
最近练习一些关于发布帖子的技术,说来也简单,就学了一点皮毛吧!好了,下面就上代码吧! 首先设计服务器的访问类,大家都知道现在东西都要联网的嘛! JSONParser的类: public class J ...
- CacheManager源码分析
计算rdd的某个分区是从RDD的iterator()方法开始的,我们从这个方法进入 然后我们进入getOrCompute()方法中看看是如何进行读取数据或计算的 getOrElseUpdate()方方 ...
- 虚拟机服务没有启动的 CentOS 和 Ubuntu 无法上网
测试用 vmware 安装 OSX,安装补丁时要停止 vmware 的服务.如下图: 结果忘记启动了,导致 centos\ubuntu 等所有虚拟机都无法上网...所有的 启动这四个服务后,一切恢复正 ...
- echarts实用小技巧,控制字符串长度,限定整数等
限定横坐标文本字符长度 xAxis : [ axisLabel:{ formatter: function (value) { var maxlength=6; if (value.length> ...
- BGP路由控制属性
控制BGP路由概述: BGP与IGP不同,其着跟点主要在于不同的AS之间控制路由的传播和选择最佳路由 通过修改BGP基本属性可以实现基本的BGP路由控制和最佳路由的选择 引入其他路由协议发现的路由时. ...
- Django的命令操作,python
忘记时候,查看命令用:python manage.py 1 建立项目的命令: django-admin.py startproject project_name 2 在项目的目录下建立app: dja ...
- 初步学习pg_control文件之十五
接前文 初步学习pg_control文件之十四 再看如下这个: int MaxConnections; 应该说,它是一个参考值,在global.c中有如下定义 /* * Primary determ ...
- 根据生产场景对Linux系统进行分区
转自:http://oldboy.blog.51cto.com/2561410/629558 老鸟谈生产场景如何对linux系统进行分区? █ 前言: 我们买房子时,会考虑1室1厅,2室1厅, ...
- Dos命令%date:~0,10%
在使用命令对数据库备份的时候,想让备份的文件以当天的日期命名.需要获取当天的日期,获取当天的日期用date命令,获取当天的时间用time命令.但时间和日期一般都是有一定格式的,而使用的时候,是不想用那 ...
- c++ list_iterator demo
#include <iostream> #include <list> using namespace std; typedef list<int> Integer ...