AT5760 Manga Market
首先一个想法就是可以考虑令 \(dp_{i, j}\) 表示当前考虑到了第 \(i\) 个商店,当前到了时刻 \(j\) 能走过最多的商店数量。但是你会发现这个 \(dp\) 转移的顺序并不是简单的从左往右转移,因为可能先走后面一个商店再走前面的一个商店,这时候我们一般的处理方法就是找到一种拓扑序使得这个 \(dp\) 能够转移。
我们会发现上面的 \(dp\) 的问题在于,可能会先走后面的商店再走前面的商店,那么我们能否对这些商店按某种方式排序后使得先走前面的商店一定比先走后面的商店更优呢?我们来试试看,对于任意两个商店 \(x, y\) 在某一时刻 \(t\) 如果先走 \(x\) 比先走 \(y\) 更优,则有:
\]
暴力拆解之后可以得到:
\]
因此我们只需要先将这些商店按照上面这个方法排序,这样就能保证转移顺序一定是从左往右了。再回到这个 \(dp\),你会发现这个 \(dp\) 的状态涉及 \(T\) 是不行的,能不能改写这个状态呢?你会发现直接将第二维和 \(dp\) 值直接调换即可,即令 \(dp_{i, j}\) 表示考虑完前 \(i\) 个商店,当前已经过 \(j\) 个商店的最小耗时。但是时间复杂度还是不够,但可以注意到的是如果 \(a_x \ne 0\) 则 \((t + 1)(a_x + 1) + b_x > 2t\) 也就是说我们最多会选 \(\log T\) 个 \(a_x > 0\) 的商店,这样我们 \(dp\) 的状态数就可以做到 \(O(n \log T)\) 了,转移的时候直接枚举上一次走的商店即可。注意到这是一个前缀 \(\max\) 的形式,\(dp\) 时一路维护前缀 \(\max\) 即可。
那么对于 \(a_x = 0\) 的商店呢?你会发现,这些 \(a_x = 0\) 的商店 \(x\) 放在最后走一定是最优的,因为如果放在前面走必然会因为后面存在一个 \(a_y > 0\) 使得 \(x\) 对时间的贡献会翻倍;而且我们一定会选择走 \(b_x\) 最小的那几个商店,所以我们先将 \(a_x = 0\) 的这部分商店按找 \(b_x\) 从小到大排序。因此,我们在最后统计答案的时候,对于每个 \(dp_{i, j}\) 找到最后一个 \(P\) 使得 \(\sum\limits_{k = 1} ^ P b_k + 1 \le T - dp_{i, j}\),直接记录 \(b\) 数组的前缀和二分即可。
#include<bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for(int i = l; i <= r; ++i)
const int N = 200000 + 5;
const int M = 30 + 5;
const int inf = 1000000000 + 1;
struct node{
int a, b;
}a[N], b[N];
int n, m, T, cnt, ans, S[N], mx[M], dp[N][M];
int read(){
char c; int x = 0, f = 1;
c = getchar();
while(c > '9' || c < '0'){ if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
bool cmp1(node x, node y){
return 1ll * x.b * y.a - 1ll * x.a * y.b < x.a - y.a;
}
bool cmp2(node x, node y){
return x.b < y.b;
}
int main(){
cnt = read(), T = read();
rep(i, 1, cnt){
a[i].a = read(), a[i].b = read();
if(!a[i].a) b[++m] = a[i];
else a[++n] = a[i];
}
sort(a + 1, a + n + 1, cmp1), sort(b + 1, b + m + 1, cmp2);
rep(i, 0, n) rep(j, 0, M - 5) dp[i][j] = mx[j] = inf;
dp[0][0] = mx[0] = 0;
rep(i, 1, n){
rep(j, 1, M - 5) if(1ll * (mx[j - 1] + 1) * (a[i].a + 1) + a[i].b <= T){
dp[i][j] = (mx[j - 1] + 1) * (a[i].a + 1) + a[i].b;
}
rep(j, 1, M - 5) mx[j] = min(mx[j], dp[i][j]);
}
rep(i, 1, m) S[i] = min(S[i - 1] + b[i].b + 1, inf);
ans = upper_bound(S + 1, S + m + 1, T) - S - 1;
rep(i, 1, n) rep(j, 1, M - 5) if(dp[i][j] < inf){
int P = upper_bound(S + 1, S + m + 1, T - dp[i][j]) - S;
ans = max(ans, j + P - 1);
}
printf("%d", ans);
return 0;
}
AT5760 Manga Market的更多相关文章
- LYDSY模拟赛day2 Market
/* orz claris,这个题的解法非常巧妙,首先是时间问题,其实这个问题只要离线处理一下就可以了,把物品和询问都按照时间排序,然后看一下能不能满足.然后,因为容量<=10^9,显然是不可能 ...
- Android网页中tel,sms,mailTo,Intent,Market协议用法总结
tel:协议---拨打电话 <a href="tel:">调出拨号界面</a> <a href="tel:10086">调 ...
- [Xamarin] 製作Options Menu、Intent 呼叫網址和Market (转帖)
Android的設計如果沒意外的話通常有三棵按鈕,BACK,HOME,OPTION (圖片來源:http://developer.android.com/design/index.html) 在OPT ...
- ZOJ 3910 Market ZOJ Monthly, October 2015 - H
Market Time Limit: 2 Seconds Memory Limit: 65536 KB There's a fruit market in Byteland. The sal ...
- 发布android app到android market的方法
转载自: http://www.stwind.org/android-market 给你的程序签名注意事项:所有提交到Market的程序必须经过签名.未经签名的程序不能安装.你可以使用个人证书去签 ...
- 在android market发布个人免费应用的步骤
写了一段时间的android应用了,只是在自己手机上面安装. 上周申请了android developer,需要一次性25美元的程序开发注册费用.费用需要用google checkout,所以还要先申 ...
- 【转】开发者教程:如何将Android应用发布到Google Play(Android Market)官方市场
原文网址:http://www.chinaapp.org/game/5594.html 作为一个专业的App开发者网站,竟然没有一篇讲述如何将Android App发布到Google Play的教程, ...
- Android Market 分析【安卓市场】
安卓市场: 通过对表的分析,“下载任务”的数据来源于数据库[app_download],“已安装”的数据来源于数据库[software_installed]. 数据分析:----- bash-3.2# ...
- android market 选择
通过Java包名直接定位到你的App http://market.android.com/details?id=<java包名>或者market://details?id=<java ...
随机推荐
- isEmpty 和 isBlank 的区别
一般使用Apache commons-lang3 工具包: commons-lang3 是专业的工具包,功能非常齐全.强大. 1.isEmpty 判断字符串是否为空字符串,只要有一个任意字符(包括空白 ...
- 在页面中添加两个 <select> 标签,用来显示年份和月份;同时添加两个 <ul> 标签,一个用来显示星期,另一个用来显示日期 在 JavaScript 脚本中动态添加年份和月份,获取当前日期的年份
查看本章节 查看作业目录 需求说明: 使用 JavaScript 中的 Date 对象,在页面上显示一个万年历.选择不同的年份和月份,在页面中显示当前月的日历 实现思路: 在页面中添加两个 <s ...
- C# 高性能对象复制
需求背景:对象复制性能优化:同时,在对象复制时,应跳过引用类型的null值复制,值类型支持值类型向可空类型的复制 -------------- 1 using Common; 2 using Syst ...
- Nginx部署及Web基础
目录 Nginx部署及Web基础 Nginx简介 Nginx特点 Web服务 Web服务器软件 Nginx和Apache对比图 部署Nginx yum安装 编译安装 平滑增加Nginx模块 Nginx ...
- rabbimq集群搭建报错:Error: unable TO perform an operation ON node 'rabbit@test3'. Please see diagnostics information AND suggestions below.
在搭建rabbitmq集群的时候,添加内存节点时,抛出异常:Error: unable TO perform an operation ON node 'rabbit@test3'. Please s ...
- nginx worker_cpu_affinity使用方法
Nginx默认没有开启利用多核CPU,我们可以通过增加worker_cpu_affinity配置参数来充分利用多核CPU.CPU是任务处理,计算最关键的资源,CPU核越多,性能就越好. 配置Nginx ...
- 【PowerShell】ASCII与Char之间的转换
1 [char[]][int[]]$char=65..90 2 $char -join ',' 3 [int[]][char[]]$ascii=$char 4 $ascii -join ',' A,B ...
- PAT 乙级 1004. 成绩排名 (20)(C语言描述)
读入n名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式:每个测试输入包含1个测试用例,格式为 第1行:正整数n 第2行:第1个学生的姓名 学号 成绩 第3行:第2个学生 ...
- Python-多线程及生产者与消费者
一.前置知识 1. 队列基础 如果不指定队列是什么,请自行查阅 在Python中,队列是最常用的线程间的通信方法,因为它是线程安全的 from queue import Queue # 创建队列 # ...
- 5.13-jsp分页功能实现
1.分页共能的实现 可以在dao层中创建方法 List<Member> pager(Long pageSize, Long pageNum);(方法灵活运用)其中传入的两个参数pageSi ...