[Noip2018普及]擺渡車


生涯回憶錄徹底摸了。。。反正也沒啥人看(

過幾天要給普及組神犇講課就尋思做一點普及題,然后差點被錘爆,,

題在luogu上找的https://www.luogu.org/problemnew/show/P5017,不貼了


首先考慮如果前后兩個人等待時間相差超過$m$(往返時間),那一定不必等,因為中間完全可以送一趟。所以我們發現這個$4e6$的$t_i$的數據范圍一定沒用......而且時間肯定要排序一下啦。

所以這肯定要dp了,用f[i][j]表示前i個人全送走,且最后一班車讓$i$等了$j$分鍾,前$i$個人總共等了多久。那么f[i][j]可以轉移到f[k][下一班車走的時間-$t_k$],表示下一班把$k$之前包括$k$的人送了。這里下一班車走的時間就是$f[i][j]$表示的發車時間$+m$和$t_k$取max。多花的時間用前綴和維護一下就行了。開始我沒考慮第二維,太菜了。。

代碼跑的還很慢,人菜常數大

#include<bits/stdc++.h>
using namespace std;
const int N=510;
const int inf=0x3f3f3f3f;
int f[N][N],a[N],s[N];
int main(){
    memset(f,63,sizeof f);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
    s[i]=s[i-1]+a[i];
    f[0][0]=0;a[0]=-inf;
    for(int i=0;i<=n;i++){
        for(int k=i+1;k<=n;k++){
            for(int j=0;j<m;j++){
                int t=max(a[k],a[i]+j+m);
                f[k][t-a[k]]=min(f[k][t-a[k]],f[i][j]+t*(k-i)-(s[k]-s[i]));
            }
        }
    }
    int ans=inf;
    for(int j=0;j<m;j++)
    ans=min(ans,f[n][j]);
    cout<<ans<<endl;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM