码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 385D - Bear and Floodlight

时间:2017-08-16 19:22:07      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:problem   http   its   c++   div   状态   com   复杂度   有一个   

385D - Bear and Floodlight

题目大意:有一个人从( l , 0 ) 想走到 ( r , 0 ),有 n 盏路灯,位置为( xi , yi ),每盏路灯都有一个照射的角度ai

这个角度内的区间都被照亮,问你走之前任意调路灯的方向,这个人只能走路灯照亮的地方,问你他最多能往

r 方向走多少距离。

 

思路:本来我想的是才20盏灯直接枚举灯的顺序也不会超时的吧,复杂度才20!* 20,结果GG,T掉了,改成

状态压缩就过了,状态压缩也跑了2000+ms。dp[ i ],表示 i 这个状态下的到达的最长距离。dp[ ( 1 << n ) - 1 ]

就是我们要用的答案,将一个路灯照亮的距离往上加的时候,用正弦定理计算距离。

技术分享
#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
const int N=20;
int n;
double l,r,dp[1<<N];
struct lit
{
    double x,y,a;
}w[21];
double dis(double x1,double y1,double x2,double y2)
{
    double a=(x1-x2)*(x1-x2);
    double b=(y1-y2)*(y1-y2);
    return sqrt(a+b);
}
double work(double pre,int g)
{
    double d=dis(pre,0,w[g].x,w[g].y);
    double c=acos(fabs(w[g].x-pre)/d);
    if(w[g].x<pre) c=pi-c;
    c=pi-w[g].a-c;
    if(c<0)
    {
        printf("%.12f\n",r);
        exit(0);
    }
    double len=d*sin(w[g].a)/sin(c);
    return min(r,pre+len);
}
int main()
{
    scanf("%d%lf%lf",&n,&l,&r);
    r-=l;
    for(int i=0;i<n;i++)
    {
        scanf("%lf%lf%lf",&w[i].x,&w[i].y,&w[i].a);
        w[i].x-=l;
        w[i].a=w[i].a/180.0*pi;
    }
    memset(dp,0,sizeof(dp));
    int up=1<<n;
    for(int i=0;i<up;i++)
    for(int j=0;j<n;j++)
    {
        if((i&(1<<j))==0) dp[i^(1<<j)]=max(dp[i^(1<<j)],work(dp[i],j));
    }
    printf("%.12f\n",dp[up-1]);
    return 0;
}
View Code

 

ps:能状压就不要枚举!!!!!!!!

Codeforces 385D - Bear and Floodlight

标签:problem   http   its   c++   div   状态   com   复杂度   有一个   

原文地址:http://www.cnblogs.com/CJLHY/p/7374986.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!