zoukankan      html  css  js  c++  java
  • Codeforces Round #433(Div. 2) D. Jury Meeting(贪心)

    题目链接:Codeforces Round #433(Div. 2) D. Jury Meeting

    题意:

    有n个城市,每个城市有一个人,现在要让这些人来0号城市在一起k天,然后回去。

    现在有m个日程表,每个日程表有出发时间,出发城市,到达城市(出发城市和到达城市其中一个为0),价钱。

    现在让你安排一个日程,使得用的总的钱最少。

    题解:

    对于每个城市的日程表去组合显然复杂度太大。

    考虑双指针的思想。在一起k天,就相当于要对每个城市找一个左端点和右端点,构成一条线段,然后n个城市构成n条线段,使得这n条线段的重叠部分大于等于k。

    那么我们考虑枚举每个k的起点L,显然在L左边,每个城市都要有左端点才行,对于每个城市如果有多个左端点,显然取最便宜的那个。

    右端点同理。

    然后就可以先预处理出:截止第i天,n个城市的人全部到达0号城市的最小花费,和全部回去的最小花费。

    然后扫一遍更新一下答案就行了。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;++i)
     3 using namespace std;
     4 typedef long long ll;
     5 
     6 const int N=1e5+7;
     7 const ll inf=1ll<<61;
     8 int n,m,k;
     9 ll dp[N*10][2],val[N];
    10 struct Node
    11 {
    12     int day,op,aim,cost;
    13     Node(int a=0,int b=0,int c=0,int d=0):day(a),op(b),aim(c),cost(d){}
    14     bool operator<(const Node &B)const{return day<B.day;}
    15 }a[N];
    16 
    17 int main(){
    18     scanf("%d%d%d",&n,&m,&k);
    19     F(i,1,m)
    20     {
    21         int aa,b,c,d;
    22         scanf("%d%d%d%d",&aa,&b,&c,&d);
    23         if(c==0)a[i]=Node(aa,0,b,d);
    24         else a[i]=Node(aa,1,c,d);
    25     }
    26     sort(a+1,a+1+m);
    27     F(i,1,n)val[i]=inf;
    28     int ed=1,cnt=0;ll sum=0;
    29     F(i,1,1000000)
    30     {
    31         while(ed<=m&&i>=a[ed].day)
    32         {
    33             if(a[ed].op){ed++;continue;}
    34             if(val[a[ed].aim]==inf)
    35             {
    36                 cnt++,val[a[ed].aim]=a[ed].cost;
    37                 sum+=a[ed].cost;
    38             }
    39             else if(val[a[ed].aim]>a[ed].cost)
    40             {
    41                 sum+=a[ed].cost-val[a[ed].aim];
    42                 val[a[ed].aim]=a[ed].cost;
    43             }
    44             ed++;
    45         }
    46         if(cnt==n)dp[i][0]=sum;
    47         else dp[i][0]=inf;
    48     }
    49     ed=m,cnt=0,sum=0;
    50     F(i,1,n)val[i]=inf;
    51     for(int i=1000000;i>=1;i--)
    52     {
    53         while(ed>=1&&i<=a[ed].day)
    54         {
    55             if(!a[ed].op){ed--;continue;}
    56             if(val[a[ed].aim]==inf)
    57             {
    58                 cnt++,val[a[ed].aim]=a[ed].cost;
    59                 sum+=a[ed].cost;
    60             }
    61             else if(val[a[ed].aim]>a[ed].cost)
    62             {
    63                 sum+=a[ed].cost-val[a[ed].aim];
    64                 val[a[ed].aim]=a[ed].cost;
    65             }
    66             ed--;
    67         }
    68         if(cnt==n)dp[i][1]=sum;
    69         else dp[i][1]=inf;
    70     }
    71     ll ans=inf;
    72     F(i,1,1000000)
    73     {
    74         if(i+k+1>1000000)continue;
    75         ans=min(ans,dp[i][0]+dp[i+k+1][1]);
    76     }
    77     printf("%lld
    ",ans==inf?-1:ans);
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    bzoj3930 [CQOI2015]选数
    bzoj4916 神犇和蒟蒻
    bzoj3439 Kpm的MC密码
    bzoj2535 [Noi2010]航空管制
    bzoj2600 [Ioi2011]ricehub
    控制和机器学习书籍推荐
    圆周率100位可以这样速记
    从哥德巴赫说开去(3)
    第一届熊赛试题解答
    Mathematical Reflections
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7489125.html
Copyright © 2011-2022 走看看