您的位置:首页 > 其它

喷水装置(二)

2018-03-25 15:37 113 查看
#include<iostream>//dp问题,求一个区间覆盖问题的贪心,和会议安排是不同的,其实核心和最长公共子序列比较像
#include<algorithm>
#include<cmath>
using namespace std;
struct F {
double x;
double r;
double l;
double begin;
double end;
}s[10000];

bool cmp1(F a, F b)
{
return a.r > b.r;
}
bool cmp2(F a, F b)
{
return a.begin < b.begin;
}
int main()
{
int T;
int N;
int w, h;
while (cin >> T)
{
while (T--)
{
while (cin >> N >> w >> h)
{

int count = 0;
int m = N;
for (int i = 0; i < N; i++)
{
cin >> s[i].x>>s[i].r;
if (s[i].r > h / 2)
{
s[i].l = sqrt(s[i].r*s[i].r - h * h / 4);
s[i].begin = s[i].x - s[i].l;
s[i].end = s[i].x + s[i].l;
}
else
m--;
}
sort(s, s + N, cmp1);//去除不符合要求的一部分
sort(s, s + m, cmp2);//按照最左端排序
double cl = 0, ml = 0;
bool flag = true;
while (cl < w)//开始dp,cl代表已经用区间覆盖的长度,ml代表下一次可以覆盖的最长长度
{
ml = 0;
for (int i = 0; i < m&&s[i].begin <= cl; i++)//s[i].begin <= cl这个条件限制不会出现区间间断

{
if (s[i].end - cl > ml)
ml = s[i].end - cl;//更新
}
;	if (ml == 0)//如果最大长度没更新,那么说明下一段区间无法被更新,那么无解
{
flag = false;
break;
}
else
{
count++;
cl += ml;
}
}
if (flag)
cout << count << endl;
else
cout << '0' << endl;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: