“深圳计算科研院杯“E起来编程暨第三届湖北省赛 B.Mr.Maxwell and attractions (优先队列,前缀和)

-
题意:你要连续\(T\)天去景点游玩(上午或者下午),有\(n\)个室内景点和\(m\)个室外景点,每个景点都有自己的值,对于同一个景点,每次重复参观,权值都要*\(0.6\).如果在下午参观室外景点那么景点的权值*\(0.8\).你至少有\(k\)天在下午游玩,问你能得到的最大权值是多少.
-
题解:对于*\(0.6\)这个条件,室内和室外都是一样的,可以用两个优先队列分别来维护,以保证它们的权值都是单调递减的,在维护的同时记两个前缀和,然后我们再\(O(n)\)遍历一遍,选\(i\)天上午去室外(\(i>(t-k)\)的部分要*0.8),\(t-i\)天下午去室内,用前缀和来更新答案.
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int n,m,t,k; double pre1[N],pre2[N]; double Max(double a,double b){ if(a>b) return a; else return b; } int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n>>m>>t>>k; k=t-k; priority_queue<double> a,b; rep(i,1,n){ double x; cin>>x; a.push(x); } rep(i,1,m){ double x; cin>>x; b.push(x); } rep(i,1,t){ double cur=a.top(); a.pop(); pre1[i]=pre1[i-1]+cur; cur*=0.6; a.push(cur); cur=b.top(); b.pop(); pre2[i]=pre2[i-1]+cur; cur*=0.6; b.push(cur); } double ans=0.0; rep(i,1,t){ if(i<=k) ans=Max(ans,pre2[i]+pre1[t-i]); else ans=Max(ans,pre2[k]+(pre2[i]-pre2[k])*0.8+pre1[t-i]); } cout<<fixed<<setprecision(2)<<ans<<'\n'; return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号