Codeforces 385D - Bear and Floodlight

Posted notnight

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 385D - Bear and Floodlight相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 653A A. Bear and Three Balls(水题)

Codeforces-A. Bear and Game(模拟)

CodeForces - 771A Bear and Friendship Condition

codeforces 653C C. Bear and Up-Down(乱搞题)

codeforces679 D. Bear and Chase

[2016-04-04][codeforces][639][A][Bear and Displayed Friends]