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 ...
随机推荐
- Categorical Reparameterization with Gumbel-Softmax
目录 概 主要内容 Gumbel distribution Jang E., Gu S. and Poole B. Categorical reparameterization with gumbel ...
- Cython编译动态库、引用C/C++文件
将某些.py 编译成动态库 设置好要编译的module们: compile_to_c_modules = [ 'package.module' ] 将它们转换成cythonize可识别的参数: def ...
- haproxy-详解
负载均衡类型: 四层: LVS (Linux Virtual Server)HAProxy (High Availability Proxy)Nginx (1.9以上) 七层: HAProxyNgin ...
- CS学习资料百度云链接
CS学习资料百度云链接 [0]Springboot微服务开发天气预报系统视频教程https://pan.baidu.com/s/1joz7flyztCq8oklBlsz8dQ提取密码:cpz7 [1] ...
- 教你10分钟对接人大金仓EF Core 6.x
前言 目前.NET Core中据我了解到除了官方的EF Core外,还用的比较多的ORM框架(恕我孤陋寡闻哈,可能还有别的)有FreeSql.SqlSugar(排名不分先后).FreeSql和SqlS ...
- 按需引入element-ui报错
按需引入element-ui报错 项目用的脚手架是 vue-cli 3 按照官方文档按需引入组件: https://element.eleme.cn/#/zh-CN/component/quickst ...
- MySQL数据库安装Version5.7
MySQL数据库版本: mysql-5.7.22-linux-glibc2.12-x86_64 Linux服务器系统: CentOS 7.4 64bit MySQL安装用户: mysql/aliyun ...
- bind 标签
<select id="finduserbylikename" parameterType="string" resultMap="cour ...
- js箭头函数 的 (e) => { } 写法笔记
1. (e) => {} 是ES 6 新语法,默认是Es 5.1,因此在这里设置一下就不会提示红色下划线了 2.使用: (e) => {} , 其实就是function (e){} 的缩 ...
- PPT2010制作图片玻璃磨砂效果
原文链接: https://www.toutiao.com/i6488928834799272462/ 选择"插入"选项卡,"图像"功能组,"图片&q ...