题目链接:http://codeforces.com/problemset/problem/629/D
题意:给你n个圆柱体的底面半径r和高h,求最大能放在一起的总体积,条件是i放到j上 Vi >= Vj 并且i > j
解析:显然是一个DP题,但数据比较大,需要优化,这里用到了map优化,就是mp[i]一直是最优的,每输入一个圆柱体i,就要二分mp里面的>=该体积的值j,存下当前值与二分到的j的上一个相加,cnt = (--R)->second + v; 然后遍历把小于cnt的值都给删了,再把mp[v] = cnt;存进去,这样就保证了所有体积都最优
借鉴 hpu 纯真学姐 博客 :http://blog.csdn.net/zwj1452267376/article/details/50720228
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<string>
#define N 1009
using namespace std;
const int INF = 0x3f3f3f3f;
typedef __int64 LL;
map<LL, LL> mp;
int main()
{
int n;
LL r, h;
scanf("%d", &n);
mp[0] = 0;
for(int i = 1; i <= n; i++)
{
scanf("%I64d %I64d", &r, &h);
LL v = r * r * h;
map<LL, LL>::iterator L = mp.lower_bound(v);
map<LL, LL>::iterator R = L;
LL cnt = (--R)->second + v; R = L;
for(; R != mp.end() && R->second <= cnt; R++) ;
mp.erase(L, R); //删除[l,r)之间元素
mp[v] = cnt;
}
printf("%.9f\n", (--mp.end())->second * acos(-1.0));
return 0;
}