努力学习DP过程中,这题与最大递增子序列相似,不过如果用一般的DP方法算法复杂度为O(n^2),TEL。因此必须改用lower_bound使复杂度降为O(nlogn)便可AC。
#include <bits/stdc++.h>
using namespace std;
const double pi = 3.141592653589793;
int n;
vector<double> cake;
int indice[100010];
int main()
{
scanf("%d",&n);
double r = 0.f;
double h = 0.f;
for (int i = 0; i < n; i++)
{
scanf("%lf%lf",&r,&h);
double temp = r*r*pi*h;
cake.push_back(temp);
}
set<pair<double, double> > S;
double result = 0.f;
for (int i = 0; i < n; i++)
{
pair<double, double> cur = make_pair(cake[i], cake[i]);
set<pair<double, double> >::iterator it1 = S.lower_bound(cur);
if (S.size() > 0 && it1 != S.begin())
{
it1--;
pair<double, double> prev = *it1;
cur.second = prev.second + cur.first;
}
while (1)
{
set<pair<double, double> >::iterator it2 = S.lower_bound(cur);
if (S.size() > 0 && it2 != S.end() && it2->second < cur.second)
{
S.erase(it2);
}
else break;
}
S.insert(cur);
result = max(result,cur.second);
}
printf("%0.9lf\n",result);
return 0;
}