当前位置:网站首页>CF【1700D】D. River Locks(dp、二分、数学)
CF【1700D】D. River Locks(dp、二分、数学)
2022-06-23 03:55:00 【阐上】
完善了下细节.
题意:
- 一个大水库由 n 个体积为 v i vi vi 升的水箱构成,每个水箱都有一个水口,开启后每秒加一升水。如果当前水箱 i 满了,多余的水会超自然地留到 i + 1 的水箱中,直到最后留到大海。
- q 次询问,每次给一个时间 t j tj tj ,问在给定时间内填满 n 个水箱最少要开启的水口数为多少,如果不能填满输出 -1.
思路:
- 显然第一步贪心,如果要开 x 个水口就开在 [1,x] ,在前面开,水溢出后可以补给后面水箱,填满的时间更短。
- 第二步比较容易走偏。其实二分都会想到,但不知道怎么下手。这里应该先推导一个公式:
- 假设已知水库总量 S,给定限定时间为 T;在这个时间限制内,要开的最少水口数其实已经确定了!,开启水口数 c n t > = S / T cnt >= S/T cnt>=S/T (上取整),满足最小所以取等于;
- cnt 确定了,之前贪心也知道是开在前 cnt 个,剩下需要确定的就是 填好前 i 个水箱的最小时间。
- 所以第三步,设置 dp 状态,转移,加上二分优化,这题就解决了。
1900的含金量
剩下看注释
C o d e : Code: Code:
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define forr(a,b,c) for(int a=b;a<=c;a++)
#define all(a) a.begin(),a.end()
#define sz(a) (int)a.size()
#define oper(a) operator<(const a& ee)const
#define endl '\n'
#define ul (u << 1)
#define ur (u << 1 | 1)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10, M = 2e5 + 10, mod = 1e8;
int INF = 0x3f3f3f3f; ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k;
//很明显的贪心,水口尽可能在前开启
int v[N], dp[N];//开启前 i 个水口,同时填满前 i 个水箱的最早时间
ll sum[N];//水量前缀和
void work() {
dp[1] = v[1], sum[1] = v[1];
for (int i = 2; i <= n; i++) {
sum[i] = sum[i - 1] + v[i];
//dp[i] 最早的时间也至少是 dp[i-1],前面填好了才能覆盖后面
int l = dp[i - 1], r = 1e9;
while (l < r)
{
int mid = l + r >> 1;
//mid是时间,i 是水口数
if (1ll * mid * i < sum[i])l = mid + 1;
else r = mid;
}
dp[i] = l;
}
}
void solve() {
cin >> n;
forr(i, 1, n)cin >> v[i];
work();
//明明我们要求的是限定时间内灌满整个水库的最少水口数,为什么dp维护的是这个呢?
//因为已知水库总量 S,给定限定时间 T;
//开启水口数 cnt >= S/T (上取整),满足最小所以取等于;
//
// 意为:满足这个开启数后,水库一定能填满,但时间不知,
// 因为单个 vi 的限制。
//
//知道要开启的水口数后,我们可以直接代入到 dp 中找到最早时间,比较即可
cin >> m;
while (m--)
{
int tim; cin >> tim;
ll g = (sum[n] + tim - 1) / tim;
if (g <= n && dp[g] <= tim)cout << g << endl;
else cout << -1 << endl;
}
}
int main() {
cinios;
int T = 1;
for (int t = 1; t <= T; t++)
solve();
return 0;
}
/* */
边栏推荐
猜你喜欢

Sift特征点提取

Thesis reading_ Relation extraction_ CASREL

计算欧式距离和余弦相似度

insert into... Where not exists insert to avoid repeated use

Beyond chips and AI, why is hard technology capital becoming more and more "hard core"?

MVC three-tier architecture

VMware network connection error unit network service not found

JSP入门级笔记

HCIP 重发布实验

Architecture à trois niveaux MVC
随机推荐
Calculate Euclidean distance and cosine similarity
轮播图的实现
掌握 Shell,一篇就够了!
直接插入排序——【常见排序法(1/8)】
使用teqcplot对teqc 质量分析结果进行可视化展示
104. 简易聊天室7:使用 Socket 传递对象
超越芯片和AI,硬科技资本为什么越来越“硬核”?
UI automation positioning edge -xpath actual combat
MVC三層架構
SwiftUI 2.0 课程笔记 Chapter 4
计算欧式距离和余弦相似度
C'est dur de trouver un emploi? Ali des trois côtés, heureusement qu'il s'est bien préparé et qu'il a pris un produit.
【Laravel系列7.8】广播系统
入行软件测试5年,跳槽3次,我摸透了软件测试这一行
【Leetcode】最长递增子序列问题及应用
【微服务|Nacos】Nacos实现多环境和多租户的数据隔离
When SBAS encounters rtklib
UI自动化定位利器-xpath实战
BGP summary of hcip operation
teqc进行GNSS数据质量分析时生成的s文件介绍