cf 629D Babaei and Birthday Cake

629D

普及组dp*2

\(n\)个蛋糕,每个蛋糕有一定体积(是圆柱体)。能把一个\(j\)蛋糕放在另一个\(i\)上面的充要条件是\(i<j\)并且\(V_i<V_j\)。问能落成的新蛋糕的最大体积。

\(dp[i]\)表示到达\(i\),且\(i\)被选,最大的体积。

\[dp[i]=max_{1\le j < i,V_j<V_i}(dp[j]+V_i)\]

离散化以后线段树或者树状数组转移都行

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T> inline T readin(T &rt) {
  char c; T tmp=0,x=1; c=getchar();
  while(c>'9' || c<'0') {if(c=='-') x=-1; c=getchar();}
  while(c>='0' && c<='9') {tmp=tmp*10+c-'0'; c=getchar();}
  return rt=tmp*x;
}

const int maxN=100000+10;
const double Pi=acos(-1.0);

int n,r[maxN],h[maxN];
ll V[maxN];
ll dp[maxN];
map<ll ,int > rfl;

typedef pair<ll ,int > pli;
#define fir first
#define sec second
#define MP make_pair
pli ck[maxN];

ll bmax[maxN];
inline int lowbit(int x) {return x&(-x);}
ll getmax(int pos) {
  ll ret=0;
  while(pos>0) {
    ret=max(ret,bmax[pos]);
    pos-=lowbit(pos);
  }
  return ret;
}
void upd(int pos,ll val) {
  while(pos<=n) {
    bmax[pos]=max(bmax[pos],val);
    pos+=lowbit(pos);
  }
}

int main() {
  readin(n);
  for(int i=1;i<=n;i++) readin(r[i]),readin(h[i]);
  for(int i=1;i<=n;i++) {
    V[i]=1ll*r[i]*r[i]*h[i];
    ck[i]=MP(V[i],i);
  }
  sort(ck+1,ck+1+n);
  int sz=unique(ck+1,ck+1+n)-(ck+1);
  for(int i=1;i<=sz;i++) rfl[ck[i].fir]=i;
  ll ans=0.0;
  for(int i=1;i<=n;i++) {
    dp[i]=getmax(rfl[V[i]]-1)+V[i];
    ans=max(ans,dp[i]);
    upd(rfl[V[i]],dp[i]);
  }
  printf("%.7lf\n",1.0*ans*Pi);
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/darkroome/p/9254949.html
今日推荐