• [NOIP2018PJ]摆渡车


    [NOIP2018PJ]摆渡车

    luogu
    mdPJ组这么难,还好考的TG组
    先按t排序
    设f[i][j]表示前i个人,第i个人等j分钟的最小总等待时间
    这里j是小于2m的
    可以考虑最坏情况下,一个人到起点时车刚好出发,m分钟之后回来
    然后车又在起点停了m分钟等别人,则这个人一共等了2m分钟
    转移分三种情况讨论:
    下一个人赶上这趟车,即t[i+1]<=t[i]+j,那么转移到f[i+1][t[i]+j-t[i+1]]
    下一个人在这趟车回来之前到了,即t[i+1]<=t[i]+j+m,枚举车回来后等待时间k,转移到f[i+1][t[i]+j+m-t[i+1]+k]
    下一个人在这趟车回来之后才到,即t[i+1]>t[i]+j+m,直接枚举等待时间k,转移到f[i+1][k]

    #include<bits/stdc++.h>
    using namespace std;
    int re(){
        int x=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*w;
    }
    int n,m,ans,t[505],f[505][205];
    void Min(int&x,int y){x=min(x,y);}
    int main(){
        n=re(),m=re();
    	for(int i=1;i<=n;i++)t[i]=re();
    	sort(t+1,t+n+1);
    	memset(f,63,sizeof(f));ans=f[0][0];
    	for(int i=0;i<m*2;i++)f[1][i]=i;
    	for(int i=1;i<n;i++){
    		for(int j=0;j<m*2;j++){
    			if(f[i][j]==ans)continue;
    			if(t[i+1]<=t[i]+j)Min(f[i+1][t[i]+j-t[i+1]],f[i][j]+t[i]+j-t[i+1]);
    			if(t[i+1]>t[i]+j+m){
    				for(int k=0;k<m*2;k++)
    					Min(f[i+1][k],f[i][j]+k);
    			}
    			else{
    				for(int k=0;t[i]+j+m-t[i+1]+k<m*2;k++)
    					Min(f[i+1][t[i]+j+m-t[i+1]+k],f[i][j]+t[i]+j+m-t[i+1]+k);
    			}
    		}
    	}
    	for(int i=0;i<m*2;i++)Min(ans,f[n][i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    2018-5-30 总结
    【数据结构系列】线段树(Segment Tree)
    Google Summer of Code 2017 经验谈
    二分查找
    Binary Indexed Tree
    Github-flavored Markdown 导出为 PDF
    Programming Languages
    Select 选择算法
    取样算法
    HTTP Status 500-Servlet.init() for servlet [springmvc] threw exception解决办法
  • 原文地址:https://www.cnblogs.com/sdzwyq/p/10031153.html
Copyright © 2020-2023  润新知