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 ...
随机推荐
- Java初学者作业——编写JAVA程序,计算跳水运动员本次动作的最终得分。
返回本章节 返回作业目录 需求说明: 编写JAVA程序,计算跳水运动员本次动作的最终得分. 规则如下: 在跳水比赛中,共有六位裁判对运动员所完成的动作进行评分,每位裁判的评分在0-10之间,运动员最终 ...
- Spring Boot 整合 Fisco Bcos(区块链)
简介 FISCO BCOS是由国内企业主导研发.对外开源.安全可控的企业级金融联盟链底层平台,由金链盟开源工作组协作打造,并于2017年正式对外开源. 目前,成熟的区块链的平台不少,之所以选择FISC ...
- spring-Ioc(二)学习笔记
属性注入方式 设值注入:也就是set注入,通过setter方法注入 java Bean private ITestDao dao; public void setDao(ITestDao dao){ ...
- linux开放端口关闭防火墙
linux开放端口关闭防火墙 systemctl status firewalld查看当前防火墙状态. 开启防火墙 systemctl start firewalld开放指定端口 ...
- IDEA maven 项目修改代码不生效,mvn clean、install 后才生效
Maven项目进行修改代码后我们重新运行代码,查看我们target目录下的class文件是否发生了变化. 如何查看class文件,鼠标移到项目,点击右键,然后点击 show in Explore ...
- zip压缩,解压
//引用 System.IO.Compression.FileSystem.dll var basePath = AppDomain.CurrentDomain.BaseDirectory; Syst ...
- 触发器中获取sql
CREATE trigger 触发器名 on 表名 for update,delete as set nocount on create table #t(EvebtType varchar(60), ...
- [硬件]USB TYPE C引脚定义
- 【刷题-LeetCode】264. Ugly Number II
Ugly Number II Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose ...
- 博客新手:图片URL的生成
作为一名博客小白,本人是在美化自己的博客时,发现自定义背景等操作需要提供图片的URL,而不是直接上传图片.那么什么是URL呢?我们又该如何获取它呢? 什么是URL 根据维基百科:统一资源定位符(英语: ...