我是靠谱客的博主 谨慎冬瓜,最近开发中收集的这篇文章主要介绍2020 ICPC沈阳站H题 The Boomsday Project,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目链接:点这里
首先,第一步要把每一次租车当作一次独立的事件提取出来,按照发生的时间进行从小到大排序,就转换为一个线性DP。
a [ i ] = p a[i] = p a[i]=p i i i 次租车的天数

f [ i ] = f [ i − 1 ] + r f[i] = f[i-1] + r f[i]=f[i1]+r 从上一次租车转移

考虑第 j j j 种办卡方式对答案的影响

f o r ( i , 1 − c n t ) / / for(i, 1-cnt)// for(i,1cnt)// i i i 次租车
f o r ( j , 1 − n ) / / for(j, 1-n)// for(j,1n)// j j j 种办卡方式

假设在处理第 i i i 次租车办第 j j j 种卡的影响下考虑第 j j j 种卡的天数和次数影响下从左往右的临界下标为 x x x ,即从 x − i − 1 x - i-1 xi1都可以通过买第 j j j 种卡转移到第 i i i 次租车,复杂度为 O ( c n t × ∑ j = 1 n m i n ( k j , d j ) × n ) O(cnttimes displaystylesum^{n}_{j = 1}{min(k_j, d_j)}times n) O(cnt×j=1nmin(kj,dj)×n) 很明显不可行
但是我们的目标仅仅是从临界下标 x − i − 1 x - i-1 xi1找到 m i n ( f [ p o s ] )   p o s ∈ [ x , i − 1 ] min(f[pos]) posin[x, i-1] min(f[pos]) pos[x,i1]
其实很显然的可以发现整个 d p dp dp数组是单调的(具体也没怎么证)
所以只要取临界值就行了
f [ i ] = m i n ( f [ i ] , f [ x ] + c j ) f[i]=min(f[i], f[x]+c_j) f[i]=min(f[i],f[x]+cj)
复杂度 O ( n × ∑ i = 1 m q i ) O(ntimes displaystylesum^{m}_{i=1}{q_i}) O(n×i=1mqi)

#include <bits/stdc++.h>
#define ll long long
#define int long long
#define pii pair<int, int>
#define rep(i, x, y) for(int i = x; i <= y; ++i)
#define dep(i, x, y) for(int i = x; i >= y; --i)
#define debug(x) cout << #x": " << x << endl;
#define ct cout << endl;
using namespace std;
const int maxn = 1e6+10;
const ll inf = 1e18;
template <typename _tp>
inline void read(_tp& x) {
char ch = getchar(), sgn = 0;
while (ch ^ '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') ch = getchar(), sgn = 1;
for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
if (sgn) x = -x;
}
struct node{
int d, k, c;
}ty[maxn];
int a[maxn], cnt;
int n, m, r;
int b[maxn], f[maxn];
signed main(){
read(n), read(m), read(r);
rep(i, 1, n) read(ty[i].d), read(ty[i].k), read(ty[i].c);
while(m--){
int p, q;
read(p), read(q);
while(q--) a[++cnt] = p;
}
sort(a+1, a+1+cnt);
rep(i, 1, cnt) f[i] = inf;
rep(i, 1, n) b[i] = 1;
rep(i, 1, cnt){
//debug(i);
f[i] = f[i-1] + r;
rep(j, 1, n){
while(a[b[j]] + ty[j].d <= a[i] || b[j] + ty[j].k <= i) b[j]++;
f[i] = min(f[b[j] - 1] + ty[j].c, f[i]);
//debug(f[i]);
}
}
printf("%lld", f[cnt]);
return 0;
}

最后

以上就是谨慎冬瓜为你收集整理的2020 ICPC沈阳站H题 The Boomsday Project的全部内容,希望文章能够帮你解决2020 ICPC沈阳站H题 The Boomsday Project所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部