买棉花糖

题目链接:YBT2023寒假Day9 B

题目大意

有 n 个商店,每个商店有 ci 个物品,原价是 ai,你在一个商店买的物品越多,下一个买的就越少,每次减少 di 块钱。
然后有 q 次询问,每次问你买 mi 个物品的最小费用。

思路

首先由一个结论,就是确定总物品数的情况下,最优情况中最多一家店选的物品数量不是 0 也不是全部。

感性的看也确实是这样,因为如果买这个越买越赚就肯定是买更多,不过还是不是那么显然,我们考虑证明:

那如果上面的条件成立,那有两家点 i , j i,j i,j,分别选了 x , y x,y x,y 个。
假设 b i , j b_{i,j} bi,j​ 是在第 i i i 个商店买第 j j j 次的价格,那 b i , j = a i − ( j − 1 ) d i b_{i,j}=a_i-(j-1)d_i bi,j​=ai​−(j−1)di​
那我们首先有 b i , x > b i , x + 1 , b j , y > b j , y + 1 b_{i,x}> b_{i,x+1},b_{j,y}>b_{j,y+1} bi,x​>bi,x+1​,bj,y​>bj,y+1​。

那如果满足最优,那就是无论 x + 1 , y − 1 x+1,y-1 x+1,y−1 和 x − 1 , y + 1 x-1,y+1 x−1,y+1 都不优。
那就是 b i , x ⩽ b j , y + 1 , b j , y ⩽ b i , x + 1 b_{i,x}\leqslant b_{j,y+1},b_{j,y}\leqslant b_{i,x+1} bi,x​⩽bj,y+1​,bj,y​⩽bi,x+1​
然后联立这个式子和上面的第一个。
b j , y ⩽ b i , x + 1 < b i , x ⩽ b j , y + 1 b_{j,y}\leqslant b_{i,x+1}<b_{i,x}\leqslant b_{j,y+1} bj,y​⩽bi,x+1​<bi,x​⩽bj,y+1​
那就是 b j , y < b j , y + 1 b_{j,y}<b_{j,y+1} bj,y​<bj,y+1​,这与上面的第二个 b j , y > b y , j + 1 b_{j,y}>b_{y,j+1} bj,y​>by,j+1​ 矛盾。
所以成立。

然后考虑通过看特别的那个位置在哪里,考虑分治。( f l , r , x f_{l,r,x} fl,r,x​ 是第 l ∼ r l\sim r l∼r 个商店里面选 x x x 个的代价)
那如果是 [ l , m i d ] [l,mid] [l,mid],那你可以先左边递归下去得到 g m = f l , m i d , m g_m=f_{l,mid,m} gm​=fl,mid,m​,然后再枚举右边 [ m i d + 1 , r ] [mid+1,r] [mid+1,r],用一个背包的操作(不加或者全加),算入到 g g g 里面。
右边也同理,那背包一次是 O ( n m ) O(nm) O(nm) 的,总复杂度就是 O ( n m log ⁡ n ) O(nm\log n) O(nmlogn)

代码

#include<cstdio>
#include<iostream>
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3fusing namespace std;const int N = 550;
const int M = 2e4 + 100;
int n, q;
ll a[N], d[N], c[N], g[N << 2][M];void slove(int now, int l, int r) {if (l == r) {for (int i = 0; i <= c[l]; i++) g[now][i] = a[l] * i - d[l] * (i - 1) * i / 2;for (int i = c[l] + 1; i <= 20000; i++) g[now][i] = INF;return ;}int mid = (l + r) >> 1;slove(now << 1, l, mid);for (int i = mid + 1; i <= r; i++) {for (int j = 20000 - c[i]; j >= 0; j--)g[now << 1][j + c[i]] = min(g[now << 1][j + c[i]], g[now << 1][j] + a[i] * c[i] - d[i] * (c[i] - 1) * c[i] / 2);}slove(now << 1 | 1, mid + 1, r);for (int i = l; i <= mid; i++) {for (int j = 20000 - c[i]; j >= 0; j--)g[now << 1 | 1][j + c[i]] = min(g[now << 1 | 1][j + c[i]], g[now << 1 | 1][j] + a[i] * c[i] - d[i] * (c[i] - 1) * c[i] / 2);}for (int i = 0; i <= 20000; i++) g[now][i] = min(g[now << 1][i], g[now << 1 | 1][i]);
}int main() {freopen("marshmallow.in", "r", stdin);freopen("marshmallow.out", "w", stdout);
//  freopen("easy2.in", "r", stdin);
//  freopen("write.txt", "w", stdout);scanf("%d %d", &n, &q);for (int i = 1; i <= n; i++) {scanf("%lld %lld %lld", &a[i], &d[i], &c[i]); c[i] = min(c[i], 20000ll);}slove(1, 1, n);for (int i = 1; i <= q; i++) {int x; scanf("%d", &x); printf("%lld\n", g[1][x]);}return 0;
}

【YBT2023寒假Day9 B】买棉花糖(DP)(分治)相关推荐

  1. 【CLYZ集训】买棉花糖【分治】【背包】

    题目大意 给定长度为 n n n的数组 a i , c i , d i a_i,c_i,d_i ai​,ci​,di​,代表编号为i的糖有 c i c_i ci​个,买第 j j j个的价值为 a i ...

  2. 【YBT2023寒假Day3 A】千与千寻(期望DP)(高斯消元)

    千与千寻 题目链接:YBT2023寒假Day3 A 题目大意 一个 n*m 的平面,你要从 (0,0) 走到 (x,y),你等概率的向上或向右走,然后当你走到 (n-1,i) 再往右走,就是 (0,i ...

  3. 【YBT2023寒假Day10 B】随机游走(记忆化搜索)

    随机游走 题目链接:YBT2023寒假Day10 B 题目大意 有 n 个点排成环,你一开始在 1 号点,每次可以等概率选择左边跳两格,左边跳一格,右边跳一格,右边跳两格. 走到一个走过的点就停止. ...

  4. 【YBT2023寒假Day11 B】催眠大师(费用流)

    催眠大师 题目链接:YBT2023寒假Day11 B 题目大意 有一个 n*n 的棋盘,有一些位置有障碍. 然后定义棋盘上两个位置能相互攻击当且仅当在同一行或同一列,且之间的所有位置都没有障碍. 多次 ...

  5. 【YBT2023寒假Day3 C】樱桃莓莓(凸包)(线段树)

    樱桃莓莓 题目链接:YBT2023寒假Day3 C 题目大意 给你一棵有根数,点有 a,b 两种权值. 然后一个点的分数是它以及它所有祖先的 a 权值和的绝对值乘上 b 权值和的绝对值. 然后有两种操 ...

  6. 【YBT2023寒假Day1 B】不跪模样(树链剖分)(线段树)

    不跪模样 题目链接:YBT2023寒假Day1 B 题目大意 给你一棵有根数,点有点权,两种操作: 对于所有 x 子树内与 x 距离不超过 2 的点,将其点权加 v. 询问 x 子树中,满足 i< ...

  7. 【YBT2023寒假Day4 C】樱桃莓莓(交互)(四毛子分块)(线段树)

    樱桃莓莓 题目链接:YBT2023寒假Day4 C 题目大意 有一个黑盒操作满足交换律和结合律,有 n 个数,q 次询问,每次选 m 个下标,你要计算所有不包含那 m 个下标的数进行黑盒操作之后的结果 ...

  8. 【YBT2023寒假Day10 C】娄居吉勾(点分树)

    娄居吉勾 题目链接:YBT2023寒假Day10 C 题目大意 有一个 n 个点 m 条边的无向连通图,每个点至多在 k 个简单环上. 然后有 q 个操作,标记一个没有标记过的点,或者给你一个点求它得 ...

  9. 【YBT2023寒假Day11 A】海妖沙龙(计算几何)

    海妖沙龙 题目链接:YBT2023寒假Day11 A 题目大意 平面上有 n 个点,然后对于一个排列,如果按顺序走对于的点,会形成若干个线段组成的路径,然后你从前一个线段走到下一个线段端点时候,你需要 ...

最新文章

  1. 机器学习入门(01)— 感知机概念、实现、局限性以及多层感知机
  2. 相当全面的Numpy使用总结.pptx
  3. TSQL查询内幕::(2.3)查询计划与更新计划
  4. ssh key生成_Stelnet(ssh)登陆华为交换机配置教程
  5. 【Flink】Flink 的 slotSharingGroup 有什么用
  6. 已经连接到空闲例程的解决方法
  7. 开个坑: gitk和git容易被滥用的 cherry-pick 功能
  8. python爬虫-Python 爬虫介绍
  9. mPaas集成项目、新建mPaaS项目
  10. java od_OD使用教程
  11. 计算机网络连接限制,网络连接受限,详细教您网络连接受限怎么解决
  12. linux修改目录的owner及group权限
  13. 防火墙双机热备升级步骤
  14. 使用git上传代码遇到关于remote: Support for password authentication was removed on August 13, 2021.的问题
  15. Ubuntu16.04使用sudo add-apt-repository时报错:aptsources.distro.NoDistroTemplateException
  16. flv.js视频播放库基本用法
  17. 没有比脚更长的路 没有比人更高的山
  18. 全网首发!IPFS团队成员详细介绍:硅谷明星团队协议实验室
  19. SCCM 2012 R2实战系列之一:SQL安装
  20. 【正点原子Linux连载】第七十章 Linux WIFI驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

热门文章

  1. 马力和扭矩到底哪个更重要?
  2. java 的 exe脱壳_[已解决]求教如何使用java编写加壳程序对PE文件进行加壳
  3. 计算机里创建本地磁盘分区,韩博士教你怎么用本地模式将电脑磁盘分区
  4. 利用SSH 或 Teamviewer 控制远程服务器
  5. 青蛙过河c语言游戏素材,博客里可爱小FLASH,超级搞笑和一款智力青蛙过河游戏..据说很少人能过河哟...
  6. 【Matlab优化预测】布谷鸟算法优化灰色模型预测【含源码 1244期】
  7. 收款收银台上快捷支付(无卡支付)方案说明
  8. MIPI2LVDS芯片TC358774XBG寄存器查看与调试
  9. 笨办法学Python 3 习题4
  10. 杨晓峰-java核心技术36讲(学习笔记)- 第1讲 | 谈谈你对Java平台的理解?