[排序][二分][dp]JZOJ 2747 捡金子
Description
从前有一个迷宫,迷宫的外形就像一棵带根树,每个结点(除了叶子结点外)恰好有K个儿子。
一开始你在根结点,根结点的K个儿子分别标记为‘A’, ‘B’, ‘C’….,而结点‘A’的K个儿子结点分别标记为‘AA’,‘AB’,‘AC’……,依此类推。这棵树一共有L层。
现在你事先知道M个结点中有金子,并且你可以派出N个机器人去收集金子。首先你可以分别指定每一个机器人的目标结点,于是这些机器人就会收集从根结点到其目标结点这条路径上(包括目标结点)所有的金子,但是每个位置的金子只能被收集一次。
现在你需要制定一个目标的分配方案,使得收集到的金子最多。
题解
首先,我们将m个结点从小到大排序
那么我们要把树造出来,其实只用将这几个用金子的结点连起来就好了
我们找到2~m的父亲(或爷爷或曾爷爷或曾曾爷爷或曾曾曾爷爷.....)(用!!二分!!实现),存入队列里边
最后就可以dp了我们设f[i][j]为以第i个结点为根,用第j个机器人的收集金子的最大数状态转移方程就是 f[x][i]=max(f[x][i],f[x][i-j]+f[y][j])(Ps: x为当前结点 i为当前枚举到用第i个机器人 y为他下一辈的结点 j为他下一辈结点用的机器人)
代码
uses math;
type strx=string[55];
var num,m,k,l,n,x,i,j:longint;next,last,first,bz:array[0..50050]of longint;a:array[0..50050]of strx;f:array[0..50050,0..50]of longint;w:string;procedure insert(i,j:longint);
begininc(num);next[num]:=last[i];last[i]:=num;first[num]:=j;
end;procedure qsort(l,r:longint);
var i,j:longint;mid,t:strx;
beginif (l>=r) then exit;i:=l; j:=r; mid:=a[(l+r) div 2];repeatwhile (a[i]<mid) do inc(i);while (a[j]>mid) do dec(j);if (i<=j) thenbegint:=a[i]; a[i]:=a[j]; a[j]:=t;inc(i); dec(j);end;until i>j;qsort(l,j);qsort(i,r);
end;function find(x:strx):longint;
var l,r,mid:longint;
beginl:=1; r:=i;while (l<r) dobeginmid:=(l+r)div 2;if (a[mid]<x)then l:=mid+1 else r:=mid;end;if (a[l]<>x) then exit(0) else exit(l);
end;procedure dp(x:longint);
var k,y,i,j:longint;
begink:=last[x];while (k<>0) dobeginy:=first[k];dp(y);for i:=n downto 1 dofor j:=1 to i dof[x,i]:=max(f[x,i],f[y,j]+f[x,i-j]);k:=next[k];end;for i:=1 to n do f[x,i]:=f[x,i]+bz[x];
end;beginreadln(m,k,l,n);for i:=1 to m do readln(a[i]);inc(m);a[m]:='';qsort(1,m);x:=1;for i:=2 to m dobeginw:=a[i];delete(w,length(w),1);j:=find(w);while (j=0) dobegindelete(w,length(w),1);j:=find(w);end;insert(j,i);bz[i]:=1;end;dp(1);writeln(f[1,n]);
end.
转载于:https://www.cnblogs.com/Comfortable/p/8412245.html
[排序][二分][dp]JZOJ 2747 捡金子相关推荐
- 【bzoj1044】[HAOI2008]木棍分割 二分+dp
题目描述 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且 ...
- 【二分】防具布置/秦腾与教学评估(ybtoj 二分-1-2/jzoj 1253/luogu 4403)
正题 ybtoj 二分-1-2 jzoj 1253 luogu 4403 题目大意 给出n组数:si,ei,dis_i,e_i,d_isi,ei,di 对于每组数据,表示在sis_isi加1, ...
- 51Nod-1090 3个数和为0【排序+二分查找】
1090 3个数和为0 基准时间限制:1秒 空间限制:131072KB 分值:5难度:1级算法题 给出一个长度为N的无序数组,数组中的元素为整数,有正有负包括0,并互不相等.从中找出所有和 = 0的3 ...
- hihocoder #1362 : 修补木桶(二分+dp)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 一只木桶能盛多少水,并不取决于桶壁上最高的那块木板,而恰恰取决于桶壁上最短的那块. 已知一个木桶的桶壁由N块木板组成,第i ...
- P3573-[POI2014]RAJ-Rally【拓扑排序,二分+树状数组】
正题 题目链接:https://www.luogu.com.cn/problem/P3573 题目大意 nnn个点mmm条边的DAGDAGDAG,删掉一个点使得最长路最短. 解题思路 先跑一遍拓扑排序 ...
- 线段树分裂与合并 ----- P2824 [HEOI2016/TJOI2016]排序 [线段树分裂合并 OR 01序列排序+二分线段树]
题目链接 题目大意: 对一个序列,每次按照升序或者降序排序序列某一段,问你最后的序列是什么? 解法1:二分+线段树 首先我们知道对一个01序列进行排序是很快的!我们只要知道里面有多少个1和多少个0,那 ...
- hdu1025 Constructing Roads In JGShining#39;s Kingdom(二分+dp)
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 Problem ...
- bzoj 1863 二分+dp check
思路:二分之后用dp去check就好啦. #include<bits/stdc++.h> #define LL long long #define fi first #define se ...
- hdu 4495(hash+二分+dp)
题意:求一个n*m的矩阵里面的最大的一个对称等腰直角三角形,三角形的腰必须平行于矩阵的边,n,m<=500. 解题思路:腰平行于矩阵的边,其实也就是做四个方向,首先找到每一个点的最长腰f[i][ ...
最新文章
- 以太坊节点布置(4) geth节点互联
- 【Spring框架】 ☞ 项目启动时执行特定处理及ApplicationListener源码分析
- 为什么“极大似然估计表达式的极值”可以用来估计参数
- kafka不使用自带zk_kafka概念扫盲
- 软件工程 speedsnail 第二次冲刺1次
- python gzip压缩文件
- 统计字段中出现字符串的次数
- maven项目发布到tomcat后没有lib目录解决方案
- hadoop mapreduce lzo
- Numpy重要模块——linalg线性代数详细参数及演示
- flex学习笔记 数据验证
- 我和权威的故事——王垠
- 填万能经营范围模板,避开办理营业执照经营范围的坑
- 安装青龙面板(不用购买服务器即可薅羊毛)Ubuntu
- 使用NanoHTTPD在Android上建立本地服务器
- 介绍一款好用的flash播放器(Vcastr 3.0 – flash video(flv) player)
- Gromacs源码收获(四)
- 汇金操盘手简易去广告方法
- PCB熔锡不良失效分析
- 如何写高质量的SCI论文摘要 Dr.Wu