牛客练习赛79E-小G的数学难题【dp,单调队列】
正题
题目链接:https://ac.nowcoder.com/acm/contest/11169/E
题目大意
给出\(n\)个三元组\((a_i,b_i,c_i)\)。
要求选出一个集合\(S\),要求
\]
且最小化\(\sum_{i\in S}c_i\)
\(1\leq T\leq 5,1\leq n\leq 1000,1\leq P\leq 10000,1\leq a_i\leq b_i\leq 2\times 10^6,1\leq c_i\leq 2\times 10^6\)
解题思路
暴力的思路是设\(f_{i,l,r}\)表示到第\(i\)个,\(a_i\)的和为\(l\),\(b_i\)的和为\(r\)时的最小值。
但是这个\(O(nP^2)\)的显然不行,发现有一个\(a_i\leq b_i\)的性质考虑怎么使用。
其实还要一个相关的性质就是两个的限制的\(P\)是相等的,虽然看起来比较废话但确实是有用的。
一个十分巧妙的\(dp\)是设\(f_{i,j}\)表示\(a_i\)的和\(\leq j\)且\(b_i\)的和\(\geq j\)。虽然这样的限制不完全,但是这样确实可以统计到最小答案且不会统计到更小答案。
转移就是
\]
这样每一层用单调队列维护就可以了
时间复杂度\(O(TnP)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1100;
ll T,n,P,a[N],b[N],c[N],f[N][N*10],q[N*10];
signed main()
{
scanf("%lld",&T);
while(T--){
scanf("%lld%lld",&n,&P);
for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
for(ll i=1;i<=n;i++)scanf("%lld",&b[i]);
for(ll i=1;i<=n;i++)scanf("%lld",&c[i]);
memset(f,0x3f,sizeof(f));f[0][0]=0;
for(ll i=1;i<=n;i++){
ll tail=0,head=1,z=-1;
for(ll j=0;j<=P;j++){
f[i][j]=f[i-1][j];
ll l=j-b[i],r=j-a[i];
while(z<r){
z++;
if(f[i-1][z]>=1e18)continue;
while(head<=tail&&f[i-1][q[tail]]>f[i-1][z])tail--;
q[++tail]=z;
}
while(head<=tail&&q[head]<l)head++;
if(head<=tail)f[i][j]=min(f[i][j],f[i-1][q[head]]+c[i]);
}
}
if(f[n][P]>=1e18)printf("IMPOSSIBLE!!!\n");
else printf("%lld\n",f[n][P]);
}
return 0;
}
牛客练习赛79E-小G的数学难题【dp,单调队列】的更多相关文章
- 牛客挑战赛30 小G砍树 树形dp
小G砍树 dfs两次, dp出每个点作为最后一个点的方案数. #include<bits/stdc++.h> #define LL long long #define fi first # ...
- 牛客练习赛51 C 勾股定理 (数学,结论)
链接:https://ac.nowcoder.com/acm/contest/1083/C来源:牛客网 题目描述 给出直角三角形其中一条边的长度n,你的任务是构造剩下的两条边,使这三条边能构成一个直角 ...
- 牛客练习赛42D(性质、数学)
题目传送 就像题解所说的,写几个可以发现有分成四段的性质:第一段是从n开始往下贪,第二段是个数字,第三段……卧槽好吧真难描述. 然后发现这个数据量可达1e9,所以考虑“二分确定序列+数学计算”的方式解 ...
- 牛客练习赛$48E$ 小$w$的矩阵前$k$大元素 堆
正解:堆 解题报告: 传送门$QwQ$ 考虑把$b$从大往小排序,然后把$a_1+b_1,a_2+b_1,...,a_n+b_1$丢到堆里,顺便记录下$b$的下标 然后每次拿出一个最大值,设为$mx= ...
- 牛客挑战赛30-T3 小G砍树
link 题目大意: n个节点的带标号无根树.每次选择一个度数为1的节点并将它从树上移除.问总共有多少种不同的方式能将这棵树删到只剩 1 个点.两种方式不同当且仅当至少有一步被删除的节点不同. 题解: ...
- 2019 牛客暑期多校 G subsequence 1 (dp+组合数)
题目:https://ac.nowcoder.com/acm/contest/885/G 题意:给你两个串,要求上面哪个串的子序列的值大于下面这个串的值的序列个数,不含前导零 思路:我们很容易就可以看 ...
- 牛客小白月赛1 G あなたの蛙は旅⽴っています【DP】
题目链接 https://www.nowcoder.com/acm/contest/85/G 思路 按照题解上的方式 存取数据 然后DP一下 就可以了 AC代码 #include <cstdio ...
- 2019牛客多校第六场J-Upgrading Technology(枚举+单调队列)
Upgrading Technology 题目传送门 解题思路 对于这题,我们可以枚举一个k从0~m,表示当前我们把所有技能最少升到了k级,且至少有一个为k级. 此时我们刚好获得了前k个d[]的收益, ...
- 牛客练习赛48 C 小w的糖果 (数学,多项式,差分)
牛客练习赛48 C 小w的糖果 (数学,多项式) 链接:https://ac.nowcoder.com/acm/contest/923/C来源:牛客网 题目描述 小w和他的两位队友teito.toki ...
- 牛客练习赛48 A· 小w的a+b问题 (贪心,构造,二进制)
牛客练习赛48 A· 小w的a+b问题 链接:https://ac.nowcoder.com/acm/contest/923/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C ...
随机推荐
- Docker创建seafile搭建私有云
docker-compose.yml version: '2.0' services: db: image: mariadb:10.1 container_name: seafile-mysql en ...
- SpringBoot跨域
第一种方法 在Controller类或方法上加上@CrossOrigin元注解 package com.wzq.test.action; import com.wzq.utils.BatchDownF ...
- Specification使用notin
废话不多说直接贴代码 Specification<Employee> employeeSpecification = new Specification<Employee>() ...
- 使用VSCode创建第一个VUE项目
vue init webpack vue_test回车,然后输入工程名称vue_test vue:Missing space before value for key 'components' 原因是 ...
- UWP AppConnection.
https://www.cnblogs.com/manupstairs/p/14582794.html
- 设置一个元素的HTML内容
问题 你需要一个元素中的HTML内容 方法 可以使用Element中的HTML设置方法具体如下: Element div = doc.select("div").first(); ...
- 十八:使用JDBC进行批处理
一.使用Statement完成批处理 1.使用Statement对象添加要批量执行SQL语句,如下: 1 Statement.addBatch(sql1); 2 Statement.addBatch( ...
- mysql ORDER BY 中文出现错误问题
在MySQL中,我们经常会对一个字段进行排序查询,但进行中文排序和查找的时候,对汉字的排序和查找结果往往都是错误的. 这种情况在MySQL的很多版本中都存在. 如果这个问题不解决,那么MySQL将无法 ...
- JAVA中多态与C++多态的区别
原文出自:http://blog.csdn.net/hihui/article/details/8604779 #include <stdio.h> class Base { public ...
- Visual Studio 2022 预览版3 最新功能解说
我们很高兴地宣布Visual Studio 2022 的第三个预览版问世啦!预览版3 提供了更多关于个人和团队生产力.现代开发和持续创新等主题的新功能.在本文中,我们将重点介绍Visual Studi ...