P5017 [NOIP2018 普及组] 摆渡车
  ziazan8nleFD 2024年08月07日 46 0
C++

思路:

考虑动态规划。

定义 \(dp_i\) 表示若有一班车在第 \(i\) 个时间出发所有人等待的时间,则状态转移方程为:

\[dp_i = dp_j + \operatorname{get}(j+1,i)(j \le i - m) \]

其中 \(\operatorname{get}(l,r)\) 表示等车时间在 \([l,r]\) 范围内的人在 \(r\) 处上车的等待时间,考虑 \(O(1)\) 求出 \(\operatorname{get}(l,r)\)

定义 \(s_i\) 表示等车时间在 \([0,i]\) 的所有人的等车时间之和,\(a_i\) 表示等车时间在 \([0,i]\) 的人的个数,则:

\[\operatorname{get}(l,r) = r \times (a_r - a_{l-1}) - (s_r - s_{l-1}) \]

此时时间复杂度优化到了 \(O(T^2)\),考虑缩小 \(j\) 的范围。

注意到若在某时刻回来,且等待不发车时间 \(>m\) 了,肯定没有中间发一次车优,则 \(j\) 的范围应该在 \([i-2m,i-m]\)

此时时间复杂度为 \(O(TM)\)

完整代码:

#include<bits/stdc++.h>
#define Add(x,y) (x+y>=mod)?(x+y-mod):(x+y)
#define lowbit(x) x&(-x)
#define pi pair<ll,ll>
#define pii pair<ll,pair<ll,ll>>
#define iip pair<pair<ll,ll>,ll>
#define ppii pair<pair<ll,ll>,pair<ll,ll>>
#define fi first
#define se second
#define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x
#define Full(a) memset(a,0,sizeof(a))
#define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout);
using namespace std;
typedef double db;
typedef unsigned long long ull;
typedef long long ll;
bool Begin;
const ll N=4e6+10; 
inline ll read(){
    ll x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
          f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return x*f;
}
inline void write(ll x){
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>9)
	  write(x/10);
	putchar(x%10+'0');
}
ll n,m,x,k,ans=1e18;
ll a[N],s[N],dp[N];
ll get(ll l,ll r){
	if(l>r)
	  return 0;
	if(!l)
	  return r*a[r]-s[r];
	return r*(a[r]-a[l-1])-(s[r]-s[l-1]); 
}
bool End;
int main(){
	memset(dp,0x7f,sizeof(dp));
	n=read(),m=read();
	while(n--){
		x=read();
		a[x]++;
		k=max(k,x);
	}
	for(ll i=1;i<N;i++){
		s[i]=s[i-1]+a[i]*i;
		a[i]+=a[i-1];
	}
	for(int i=0;i<m;i++)
	  dp[i]=get(0,i);
	for(int i=m;i<=k+m;i++)
	  for(int j=max(0ll,i-2ll*m);j<=i-m;j++)
		dp[i]=min(dp[i],dp[j]+get(j+1,i));
	for(int i=k;i<=k+m;i++)
	  ans=min(ans,dp[i]);
	write(ans); 
	cerr<<'\n'<<abs(&Begin-&End)/1048576<<"MB";
	return 0;
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年08月07日 0

暂无评论

推荐阅读
ziazan8nleFD