西电2021校赛选拔赛 C.扶梯问题 (贪心,枚举)
Posted Accelerator
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了西电2021校赛选拔赛 C.扶梯问题 (贪心,枚举)相关的知识,希望对你有一定的参考价值。
-
题意:有\\(n\\)个人轮流上电梯,电梯送完一个人需要\\(1\\)个时刻.电梯有待机和运行两种状态,待机每时刻消耗\\(E_2\\)电量,运行每时刻消耗\\(E_1\\)电量,若电梯无人使用经过\\(k\\)个时刻后会变为待机状态,从待机状态变成运行状态需要消耗\\(E_3\\)电量,你可以自定义\\(k\\)的值,求出最后一个人走完后的最小消耗总电量.
-
题解:先求出任意两人之间的时间差并排序,假设\\(k=0\\),如果我们要延长\\(k\\),该怎么延长?很明显,将两人之间的差填满一定是最优的,这样可以省去一(多,因为可能有很多相同的时间差)次启动的额外电量,如果不是为了贪心减少这一(多)次启动电量,那肯定没必要延长\\(k\\),那么这题就很简单了,枚举每段时间差,依次填满维护答案.
-
代码:
#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,k; ll e1,e2,e3; //e1:运行耗电 e2:待机耗电 e3:切换耗电 k:转待机时间 int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int _; cin>>_; while(_--){ cin>>n>>e1>>e2>>e3; vector<ll> t(n+1); rep(i,1,n) cin>>t[i]; vector<ll> diff(n+1); ll num=n; ll runt=n*(e1-e2); ll k=0; ll mi=1e18; rep(i,2,n){ diff[i]=t[i]-t[i-1]-1; if(diff[i]==0) num--; } sort(diff.begin()+2,diff.end()); mi=min(mi,runt+num*e3); for(int i=2;i<=n;++i){ if(diff[i]==0) continue; int last=i; for(int j=i;j<=n;++j){ if(diff[i]==diff[j]){ last=j; } else break; } runt+=(num-1)*(diff[i]-k)*(e1-e2); k=diff[i]; num-=(last-i)+1; mi=min(mi,runt+num*e3); i=last; } cout<<mi+e2*(t[n]+1); if(_!=0) cout<<\'\\n\'; } return 0; }
以上是关于西电2021校赛选拔赛 C.扶梯问题 (贪心,枚举)的主要内容,如果未能解决你的问题,请参考以下文章
C. A and B and Team Training1300 / 思维 贪心 枚举