2020icpc沈阳H
优化转移DP
题意
Aloha 要骑单车,可以单独花费 \(r\) 元骑 1 次,也可以购买某一种单车卡,第 \(i\) 种单车卡 \(c_i\) 元,若在第 \(t\) 天购买,可以在 \([t,t+d_i-1]\) 天使用,并且最多使用 \(k_i\) 次
给出 Aloha 一段时间内的单车使用情况,求出他需要的最小花费
给出
\(n\;(1<=n<=500)\), 单车卡的种类
\(m\;(1<=m<=10^5)\), \(m\) 条使用记录
\(r\;(1<=r<=10^9)\), 单独骑 1 次的花费
\(n\) 行,每行有 \(1<=d_i,k_i,c_i<=10^9\), 第 \(i\) 种单车卡的有效期、使用次数、价格
\(m\) 行,每行有 \(0<=p_i<=10^9,\;0<=q_i<=3e5,\;\sum\limits_{i=1}^mq_i<=3e5\)
表示在第 \(p_i\) 天骑了 \(q_i\) 次
思路
看上去就是 DP,观察数据范围,很多数据的值域过大,只有 \(n\) 和 \(\sum q_i\) 可能与 DP 复杂度有关
求出每次骑的时间 \(a[i]\), 一共骑了 cnt 次,并按时间排序;
设 \(f[i]\) 为骑完前 \(i\) 次的最小花费,\(ptr[i][j]\) 为如果第 \(i\) 次可以用到第 \(j\) 个卡,则最早在第 \(ptr[i][j]\) 次骑完后买卡
可列出朴素DP转移
for (int i = 1; i <= cnt; i++)
{
f[i] = f[i - 1] + r;//初始化为不买卡直接骑
for (int j = 1; j <= n; j++)
{
auto [d, k, c] = b[j];
for (int w = ptr[i][j]; w < i; w++)
f[i] = min(f[i], f[w] + c);
}
}
由于 \(f[i]\) 是单调不减的,因此 \(f[i]=min(f[i],f[w]+c)\) 中 \(w=ptr[i][j]\) 时是最优的(也可以感性地感受一下,这样卡的利用率更高,这样好像倒推更好理解一点,有时间试试)
接下来就是需要求出 \(ptr[i][j]\),第一维可以优化掉,\(ptr[j]\) 表示第 i 次骑车时,最早需要 \(ptr[j]\)次后买第 j 种卡才能覆盖第 i 次
随着 \(i\) 增大,\(ptr[j]\) 不会回退,因此可以暴力 check,双指针维护
代码
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
typedef pair<int, int> PII;
const int N = 3e5 + 10;
int n, m;
ll r;
struct Cards
{
ll d, k, c;
}b[510];
int a[N];//第i次的时间
int cnt;
ll f[N];//前i次的最小代价
int ptr[510];
bool check(int now, int card)
{
int last = ptr[card];
auto [d, k, c] = b[card];
if (last == now)
return true;
if (a[last] + d - 1 < a[now])
return false;
if (now - last + 1 > k)
return false;
return true;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m >> r;
for (int i = 1; i <= n; i++)
cin >> b[i].d >> b[i].k >> b[i].c;
for (int i = 1; i <= m; i++)
{
int p, q;
cin >> p >> q;
while(q--)
a[++cnt] = p;
}
sort(a + 1, a + cnt + 1);
for (int i = 1; i <= n; i++)
ptr[i] = 1;
for (int i = 1; i <= cnt; i++)
{
f[i] = f[i-1] + r;
for (int j = 1; j <= n; j++)
{
auto [d, k, c] = b[j];
// for (int w = ptr; w < i; w++)
// f[i] = min(f[i], f[w] + c);
// 因为f[i]单调递增,因此取w=x最小,ptr为在第ptr次后买优惠券,正好可以覆盖到第i次,双指针更新ptr
while(!check(i, j))
ptr[j]++;
f[i] = min(f[i], f[ptr[j] - 1] + c);
// cout << i << ": " << j << " " << ptr[j] << endl;
}
}
cout << f[cnt] << endl;
return 0;
}
2020icpc沈阳H的更多相关文章
- 2020ICPC沈阳站C题 Mean Streets of Gadgetzan
大致题意 原题链接 翻译 \(有n个逻辑变量 请你分别对它们赋值 使其满足m个命题\) \(命题有四种格式:\) 单独数字x 表示第x个逻辑变量为真 ! + 数字x 表示第x个逻辑变量为假 若干个数字 ...
- 每日一刷(2018多校水题+2016icpc水题)
11.9 线段树 http://acm.hdu.edu.cn/showproblem.php?pid=6315 求逆序对个数 http://acm.hdu.edu.cn/showproblem.php ...
- 2019~2020icpc亚洲区域赛徐州站H. Yuuki and a problem
2019~2020icpc亚洲区域赛徐州站H. Yuuki and a problem 题意: 给定一个长度为\(n\)的序列,有两种操作: 1:单点修改. 2:查询区间\([L,R]\)范围内所有子 ...
- 2016ACM/ICPC亚洲区沈阳站 - A/B/C/E/G/H/I - (Undone)
链接:传送门 A - Thickest Burger - [签到水题] ACM ICPC is launching a thick burger. The thickness (or the heig ...
- 2016ACM/ICPC亚洲区沈阳站H - Guessing the Dice Roll HDU - 5955 ac自动机+概率dp+高斯消元
http://acm.hdu.edu.cn/showproblem.php?pid=5955 题意:给你长度为l的n组数,每个数1-6,每次扔色子,问你每个串第一次被匹配的概率是多少 题解:先建成ac ...
- 2019沈阳icpc网络赛H德州扑克
题面:https://nanti.jisuanke.com/t/41408 题意:A,2,3,4,5,6,7,8,9,10,J,Q,K,13张牌,无花色之分,val为1~13. 给n个人名+n个牌,输 ...
- 2016ACM/ICPC亚洲区沈阳站-重现赛赛题
今天做的沈阳站重现赛,自己还是太水,只做出两道签到题,另外两道看懂题意了,但是也没能做出来. 1. Thickest Burger Time Limit: 2000/1000 MS (Java/Oth ...
- HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)
Recursive sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- HDU 5952 Counting Cliques 【DFS+剪枝】 (2016ACM/ICPC亚洲区沈阳站)
Counting Cliques Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- HDU 5948 Thickest Burger 【模拟】 (2016ACM/ICPC亚洲区沈阳站)
Thickest Burger Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
随机推荐
- Django简介以及基本使用
目录 Django简介以及基本使用 一.django简介 1.web框架的本质是什么 ? 2.python主流web框架有那些 ? 3.web框架的推导过程 二.基本使用 1.运行django注意事项 ...
- Linux的串口非标准波特率设置更改
用的是全志的R528 SDK,Linux内核是5.4,新增加一个250000的非标准波特率 参考网络大神文档,实践并记录宝贵的经验. 方法: 1.修改内核的/include/uapi/asm-gene ...
- JavaScript 内存管理及垃圾回收
一.内存管理 JavaScript 是一种自动垃圾回收语言,这意味着 JavaScript 引擎会自动监测和清理无用的内存. JavaScript 中的内存管理主要由 JavaScript 引擎负责, ...
- 深入Typescript--03-Typescript中的类(努力加餐饭)
Typescript中的类 一.TS中定义类 class Pointer{ x!:number; // 实例上的属性必须先声明 y!:number; constructor(x:number,y?:n ...
- angular11报错Can't bind to 'ngForOf' since it isn't a known property of 'tr'. 三种排查办法以及解决方案
当你遇到Can't bind to 'ngForOf' since it isn't a known property of 'tr'. (" //无法绑定到"ngforof&qu ...
- Codeforces Round #601 (Div. 2) A-E
比赛链接 A 题意 给两个数字 \(a,b\) ,每次操作可以使 \(a\) 加上 \(+1,+2,+5,-1,-2,-5\) 中的一个数,求最少多少次操作可以将 \(a\) 变成 \(b\) . 题 ...
- 【分析笔记】NXP PCF85263 设备驱动分析笔记
驱动移植 供应商无法提供相应的驱动程序,不过在 linux 最新的内核倒是有一份 pcf85363 的驱动,看代码并核对寄存器功能,是可以兼容 pcf85263 芯片.只是我们用的内核比较老 linu ...
- 用Java写一个分布式缓存——RESP服务端
前言 本篇我们将完成一个RESP的socket的服务端,初步完成一个单机版缓存. 另外在其中我们还需要完成命令的动态路由 源码:https://github.com/weloe/Java-Distri ...
- 计算机网络基础02-Internet结构,网络核心的数据交换,计算机网络性能几个参数
1 计算机网络的结构 1.1 网路边缘 主机.应用(软件.网站) 1.2 接入网络 1.3 网络核心 转发设备,路由器.交换机.关键功能就是路由+转发达到数据交换. 2 Internet的结构 2.1 ...
- 5步带你入门GaussDB(DWS)的GDS导入导出
摘要:本篇文档为使用GDS导入示例的具体简单步骤和示例. 本文分享自华为云社区<带你快速入门GDS导入导出,玩转PB级数仓GaussDB(DWS)>,作者: yd_220527686. 1 ...