NOIp2018普及組-擺渡車

(作爲一名已經離開了普及組的退役選手感到萬分慶幸)

題目鏈接:https://www.luogu.org/problemnew/solution/P5017

1.感覺就是一個類似線性的以時間作爲維度的dp,再一看範圍:4*10^6 沒啥大問題。

2.開始思考f[t]的含義:擺渡車在t分鐘離開時所有人最少的等待時間。

3.接着就是轉移:首先比t早出發2*m分鐘之前(浪費啊)的和m分鐘之後的(轉移不了)都可以不考慮

4.最後,枚舉j從i-2*m到i-m的方案加上這一段時間內的轉移,就是我們的答案了。

(5.但是,由於CCF的機器一言難盡,,,所以我們還是考慮一下優化吧。。。如果在i-i-m之間都沒有人的話,那麼i其實可以直接賦值,不用計算了)

over

#include <bits/stdc++.h>

using namespace std;
const int maxn=5000005;
int t[maxn],num[maxn],st[maxn],f[maxn];int T=0;
int main()
{
	int n,m;scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&t[i]);num[t[i]]++;
		T=max(T,t[i]);
		st[t[i]]+=t[i];
	}
	for(int i=1;i<=T+m-1;i++)
	{
		num[i]+=num[i-1];st[i]+=st[i-1];
	}
	int minv=0x3f3f3f3f;
	for(int i=1;i<=T+m-1;i++)
	{
		if(i>=m&&num[i-m]==num[i]) {f[i]=f[i-m];continue;}//中間沒有點,直接轉移即可 
		f[i]=num[i]*i-st[i];
		for(int j=i-m;j>=max(0,i-2*m);j--)
		{
			f[i]=min(f[i],f[j]+(num[i]-num[j])*i-(st[i]-st[j]));
		}
	}
	for(int i=T;i<=T+m-1;i++) minv=min(minv,f[i]);
	printf("%d",minv);
	return 0;
 } 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章