San(COCI2017.2)题解
题意
一个人为了楼顶的金币要去跳楼,但是不能往更矮的楼上跳。
求在一个长为N的序列中总点权值和大于等于K的不下降序列数。
N<=40,K<=4e10
官方题解
折半搜索的经典例子!N在20范围内搜索能过,40范围内需要折半,由于只能向右跳,所以可以先离散化高度后将数据分为左右两部分,分别DFS出两边的合法状态(每个状态就是合法的大楼高度不下降子序列,其中包含两个属性(子序列中val价值总和,左半边是最后1个楼的高度h,而右半边是第一个楼的高度h)),然后再排序考虑合并。左半部按价值总和从大到小排序,右半部从小到大排序,统计右半部的各种高度前缀和。
双指针从左往右扫,统计合法的方案数。
方法二:只对右半部分按总金币从小到大排序,保持valL+valR≥K && hL≤hR,二分对右半部分查找并匹配左半部分。
本人题解
一看这个K,肯定要开long long ,由于N很小,空间不涉及金币数是绝对没问题的,用暴力搜索是O(2^N)必定会超时。
如果单单是求以 i 开头的金币最多的子序列,我们可以用DP求,如果单单是求以 i 开头的子序列数,我们也可以用DP求,但是题目把它们结合了,而且限制了金币数的下限,虽然我们可以预处理DP判断以 i 开1头的最多金币数是否达标……
没错,只要我们可以O(1)判断以 i 开头的最多金币数是否达标,就可以是很不错的剪枝。
此外,若 i 本身的金币数就达标了,那answer岂不是直接加上以 i 开头的子序列数?
这两个剪枝一加上,我们的搜索就能变快许多倍。而且都可以用DP预处理。
考虑时间复杂度,answer包含的情况我们肯定算过,而不在answer中的方案,我们肯定在序列中第一个无效点就return了,所以最坏情况是O(answer),可以过。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#define max(x,y) ((x) > (y) ? (x) : (y))
#define min(x,y) ((x) < (y) ? (x) : (y))
#define abs(x) ((x) < 0 ? -(x) : (x))
#define LL long long
#define lowbit(x) (-(x) & (x))
using namespace std;
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
return x * f;
}
LL n,m,i,j,o,k,cnt;
LL h[45],g[45];
LL dp1[45],dp2[45];//最大金币数,子序列数
LL dfs(int x,LL mon) {
LL as = 0;
if(dp1[x] < mon) return 0;
if(g[x] >= mon) return dp2[x];
for(int i = x + 1;i <= n;i ++) {
if(h[i] >= h[x]) {
as += dfs(i,mon - g[x]);
}
}
return as;
}
int main() {
n = read();m = read();
for(int i = 1;i <= n;i ++) {
h[i] = read();
g[i] = read();
}
for(int i = n;i >= 0;i --) {//DP预处理
dp1[i] = g[i];
dp2[i] = 1;
for(int j = n;j > i;j --) {
if(h[j] >= h[i]) {
dp1[i] = max(dp1[i],dp1[j] + g[i]);
dp2[i] += dp2[j];
}
}
}
printf("%lld\n",dfs(0,m));
return 0;
}
San(COCI2017.2)题解的更多相关文章
- 网络流24(san)题题解汇总
开坑(烂尾预定 1.餐巾计划问题 题解 2.最小路径覆盖问题 题解 3.试题库问题 题解 4.[CTSC1999]家园 题解 5.骑士共存问题 题解 6.最长不下降子序列问题 题解 7.深海机器人问题 ...
- Usmjeri(COCI2017.2)题解
题意 给一棵N个节点的树,编号从1到N,再给定m对点(u,v),你要将树上的每条无向边变为有向边,使得给定的点对都满足u能到达v或v能到达u.问有多少种不同的方案,答案对(1e9+7)求余. 1 ≤ ...
- 题解 P4093 【[HEOI2016/TJOI2016]序列】
这道题原来很水的? noteskey 一开始以为是顺序的 m 个修改,然后选出一段最长子序列使得每次修改后都满足不降 这 TM 根本不可做啊! 于是就去看题解了,然后看到转移要满足的条件的我发出了黑人 ...
- PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)
PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++: 欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...
- coci2018 题解
plahte 给定一些矩形和一些有颜色的点,求每个矩形上有多少种颜色的点,保证矩形只有包含和不相交两种关系,规模 \(10^5\). 把每个矩形看成一个点,用扫描线建出森林,同时也顺便处理点. 然后做 ...
- 【JZOJ6229】【20190621】san
题目 \(n\)个点\(m\)条边的有向图,每个点有点权 你可以选择拓扑序的一个区间的 最大化点权和 $n \le 50 , m \le \frac{n*(n-1)}{2} , 0 \le |a_i ...
- 2016 Multi-University Training Contest 4 部分题解
1001,官方题解是直接dp,首先dp[i]表示到i位置的种类数,它首先应该等于dp[i-1],(假设m是B串的长度)同时,如果(i-m+1)这个位置开始到i这个位置的这一串是和B串相同的,那么dp[ ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
随机推荐
- JZOJ 5409 Fantasy & NOI 2010 超级钢琴 题解
其实早在 2020-12-26 的比赛我们就做过 5409. Fantasy 这可是紫题啊 题目大意 给你一个序列,求长度在 \([L,R]\) 区间内的 \(k\) 个连续子序列的最大和 题解 如此 ...
- LoRa无线传输技术与LoRaWAN无线模块的区别
有不少人分不清LoRaWAN无线模块与LoRa网关无线传输技术到底有什么区别,他们在物联网领域的应用到底是什么样的. LoRaWAN指的是MAC层的组网协议,而LoRa是一个物理层的协议.虽然现有的L ...
- Java-SpringBoot-使用多态给项目解耦
Java-SpringBoot-使用多态给项目解耦 提及 今天在打算维护一下智慧社区这个项目的时候,想到项目是使用Satoken这个开箱即用的授权和认证的组件,因为在项目开启的时候对SpringSec ...
- 21.LVS负载均衡群集-DR群集
LVS负载均衡群集-DR群集 目录 LVS负载均衡群集-DR群集 数据包流向分析 DR模式的特点 LVS-DR中的ARP问题 IP地址冲突 解决办法 路由根据ARP表项,会将新来的请求报文转发给Rea ...
- JS:构造函数
定义:在JavaScript中,用new关键字来调用的函数,称为构造函数,构造函数首字母一般大写. 理解: 构造函数就是初始化一个实例对象,对象的prototype属性是继承一个实例对象. 创建对象, ...
- 我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言:一个Bug 没想到一个Bug,竟然搞我两次! 我大抵是卷上瘾了,横竖都睡不着,坐起来 ...
- UiPath程序设计文档
1. [RPA之家]添加数据列UiPath.Core.Activities.AddDataColumn 链接: https://pan.baidu.com/s/1RRMw4voqJru-fJSoC3W ...
- UiPath文本操作Set Text的介绍和使用
一.Set Text的介绍 向输入框/文本框写入文本的一种操作 二.Set Text在UiPath中的使用 1.打开设计器,在设计库中新建一个Sequence,为序列命名及设置Sequence存放的路 ...
- appium简单使用
App 测试通常会用到的工具 adb :Android 的控制工具,用于获取Android的各种数据和控制 Appium Desktop:内嵌了Appium Server和Inspector的综合工具 ...
- 平衡树——splay 三
前文链接: 平衡树--splay 一 - yi_fan0305 - 博客园 (cnblogs.com) 平衡树--splay 二 - yi_fan0305 - 博客园 (cnblogs.com) 再补 ...