LOADING

加载过慢请开启缓存,浏览器默认开启

daily 2

2023/6/17 daily

CF 777E
典中典 优先队列的状态选择问题,典行的dp

struct node{
    int a,b,h;
    bool operator <(const node& aa)const{
        if(b==aa.b){
            return a>aa.a;
        }
        return b>aa.b;
    }
};
struct sta{
    int w,h;
    bool operator <(const sta& a)const{
        return h<a.h;//p should use opposite
    }
};
void solve(){
  int n;
  cin>>n;
  vector<node>arr(n+1);
  for(int i=1;i<=n;++i)cin>>arr[i].a>>arr[i].b>>arr[i].h;
  sort(arr.begin()+1,arr.end());
  priority_queue<sta>q;
  q.push({0,0});
  int ans=-1;
  for(int i=1;i<=n;++i){
    while(q.top().w>=arr[i].b){
        q.pop();
    }
    ans=max(ans,q.top().h+arr[i].h);
    q.push({arr[i].a,q.top().h+arr[i].h});
  }
  cout<<ans<<'\n';
  return;
}

CF 796C

看题解做的,还是有点不太理解

总之答案共有三种 max+1,max,max+2(这个不难理解)

什么时候为max?就是只有一个点为max,且剩下的max-1都在一个点的邻居里

什么时候为max+1?就是所有的max的点都可以在一个点的子树里

剩下的时候都是max+2

void solve(){
  int n;
  cin>>n;
  vector<int>a(n+1);
  int max_=-INF;
  for(int i=1;i<=n;++i){
    cin>>a[i];
    max_=max(a[i],max_);
  }
  vector<vector<int>>E(n+1);
  for(int i=1;i<=n-1;++i){
    int u,v;
    cin>>u>>v;
    E[u].push_back(v);
    E[v].push_back(u);
  }
  vector<pii>info(n+1);
  int max_cnt=0,max_minus_cnt=0;
  for(int i=1;i<=n;++i){
    if(a[i]==max_){
        ++max_cnt;
    }
    if(a[i]==max_-1){
        ++max_minus_cnt;
    }
  }
  for(int i=1;i<=n;++i){
    int m_c=0,m1_c=0;
    if(a[i]==max_){
        ++m_c;
    }if(a[i]==max_-1){
        ++m1_c;
    }
    for(int v:E[i]){
        if(a[v]==max_){
            ++m_c;
        }
        if(a[v]==max_-1){
            ++m1_c;
        }
    }
    info[i]=make_pair(m_c,m1_c);
  }
  int r;
  for(int i=1;i<=n;++i){
    if(a[i]==max_){
        r=i;
        break;
    }
  }
  if(max_cnt==1){
    if(info[r].second==max_minus_cnt){
        cout<<max_<<'\n';
        return;
    }
  }
  for(int i=1;i<=n;++i){
    if(info[i].first==max_cnt){
        cout<<max_+1;
        return;
    }
  }
  cout<<max_+2<<'\n';
  return;
}