【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 − ( j − 1 ) d i a_i-(j-1)d_i ai−(j−1)di
再给出 q q q个数 m m m,问买m个糖的最小价值为多少。
思路:
首先得推出一个结论:最优方案至多存在一种糖使得它被买的个数在1到 c i − 1 c_i-1 ci−1之间。
证明:假设最优方案中有 i i i物品和 j j j物品,它们选取的个数 x , y x,y x,y在1到 c x − 1 c_x-1 cx−1和 c y − 1 c_y-1 cy−1之间,那么满足 b i , x < b j , y + 1 b_{i,x}<b_{j,y+1} bi,x<bj,y+1和 b j , y < b i , x + 1 b_{j,y}<b_{i,x+1} bj,y<bi,x+1(其中 b i , j b_{i,j} bi,j是第i种糖选第j个的价值)。这和数组 b b b的定义是矛盾的,所以得证。
那么就直接分治,分类那个1到 c i − 1 c_i-1 ci−1在左边还是右边,然后背包进行转移。
c o d e code code
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long longusing namespace std;const ll MAXN = 500 << 2;ll n, q;
ll a[MAXN], c[MAXN], d[MAXN];
ll f[MAXN][20100];void solve(ll k, ll l, ll r) {if(l == r) {for(ll i = 0; i <= c[l]; i ++) f[k][i] = a[l] * i - i * (i - 1) / 2 * d[l];for(ll i = c[l] + 1; i <= 20000; i ++) f[k][i] = 1e18;return ;}ll mid = l + r >> 1;solve(k << 1, l, mid);for(ll i = mid + 1; i <= r; i ++)for(ll j = 20000 - c[i]; j >= 0; j --)f[k << 1][j + c[i]] = min(f[k << 1][j + c[i]], f[k << 1][j] + a[i] * c[i] - c[i] * (c[i] - 1) / 2 * d[i]);solve(k << 1 | 1, mid + 1, r);for(ll i = l; i <= mid; i ++)for(ll j = 20000 - c[i]; j >= 0; j --)f[k << 1 | 1][j + c[i]] = min(f[k << 1 | 1][j + c[i]], f[k << 1 | 1][j] + a[i] * c[i] - c[i] * (c[i] - 1) / 2 * d[i]);for(ll i = 0; i <= 20000; i ++) f[k][i] = min(f[k << 1][i], f[k << 1 | 1][i]);
}int main() {freopen("marshmallow.in", "r", stdin);freopen("marshmallow.out", "w", stdout);scanf("%lld%lld", &n, &q);for(ll i = 1; i <= n; i ++) {scanf("%lld%lld%lld", &a[i], &d[i], &c[i]);if(c[i] > 20000) c[i] = 20000;} solve(1, 1, n);while(q --) {ll x;scanf("%lld", &x);printf("%lld\n", f[1][x]);}return 0;
}
【CLYZ集训】买棉花糖【分治】【背包】相关推荐
- 【YBT2023寒假Day9 B】买棉花糖(DP)(分治)
买棉花糖 题目链接:YBT2023寒假Day9 B 题目大意 有 n 个商店,每个商店有 ci 个物品,原价是 ai,你在一个商店买的物品越多,下一个买的就越少,每次减少 di 块钱. 然后有 q 次 ...
- HDUOJ----4501小明系列故事——买年货(三维背包)
小明系列故事--买年货 Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tota ...
- [SPOJ - FTOUR2] Free tour II(点分治 + 背包dp + 启发式合并)
SPOJ - FTOUR2 Free tour II problem 给定一棵树,以及 mmm 个拥挤城市编号,选择一条最多包含 kkk 个拥挤城市的简单路径. 每条边有一个有趣度 www,可正可负. ...
- P6240 好吃的题目(分治+背包)
P6240 好吃的题目 类似于线段树分治,在每个节点预处理[l,mid],[mid+1,r][l,mid],[mid+1,r][l,mid],[mid+1,r]的背包,然后询问即可 一般代码就类似下面 ...
- hdu 4501 小明系列故事——买年货 多重背包
小明系列故事--买年货 Time Limit: 500 ...
- 【题解】【LibreOJ Round #6】花团 LOJ 534 时间线段树分治 背包
Prelude 题目链接:萌萌哒传送门(/≧▽≦)/ Solution 如果完全离线的话,可以直接用时间线段树分治来做,复杂度\(O(qv \log q)\). 现在在线了怎么办呢? 这其实是个假在线 ...
- 【题解反思】海亮信息集训A-B班-分治初步专项
一.山楂关卡 题意简述: 小 VHOS 带着 N 颗山楂球来到 A 班的阵地准备缩到位置上吃山楂球. 但是 A 班大佬们太强了,所以小 VHOS 每经过一个 A 班大佬身边, 他都需要交出他手中 ...
- hdu2191 买大米 多重背包 模板题
念512汶川大地震遇难同胞--珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- 【CLYZ集训】催眠大师【费用流】
题目大意 给定一个 n × m n\times m n×m 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 ( x , y ) , ( u , v ) (x,y),(u,v) (x,y) ...
最新文章
- 安装mysql的rpm包报错_rpm包在centos6.5中安装mysql5.7初始化报错的处理办法
- 多选框向后台传值,多选框的回显,对多选框的各种操作
- ASP.NET MVC 源代码 剖析
- 网页图表Highcharts实践教程之标签组与载入动画
- 现代软件工程 第六章 【敏捷流程】练习与讨论
- python 第13章:面向对象编程
- SpringBoot 操作 Redis的各种实现(以及Jedis、Redisson、Lettuce的区别比较)
- java中怎么创建栈_这个题如何用栈解呢?
- Pyshark获取data-text-lines字段的值
- Rust : rand库与不同分布下的随机数产生
- Docker 视频教程 ( 猿课 )
- MII2RGMII IP核使用设计举例
- linux火狐快捷键设置,使用火狐浏览器所有的快捷键大全
- python import math什么意思_python中math.ceil什么意思
- Java 设置添加ckeditor图片上传功能
- 东北大学OJ-1212: 实验3-4 :scanf、printf测试
- 本科生毕业论文(设计)撰写规范
- 纸牌游戏——小猫钓鱼(队列、栈)
- 微信二维码生成步骤(本人亲测)
- 抖音很火的计算机音乐,抖音最近很火的几首背景音乐(BGM),推荐给大家很好听...