CodeForces 385 D.Bear and Floodlight 状压DP

枚举灯的所有可能状态(亮或者不亮)(1<<20)最多可能的情况有1048576种

dp【i】表示 i 状态时灯所能照射到的最远距离(i 的二进制中如果第j位为0,则表示第j个灯不亮,否则就是亮)

当i&(1<< j)时代表第i个状态灯j不亮,此时可由状态i转移到状态 i ^ ( 1 << j) 即dp[(i^(1<<j))]=max(dp[(i^(1<<j))],get(dp[i],j))

get是从dp【i】的位置开始第j个灯所能照亮的最长距离

求距离时用反三角函数比较快

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cassert>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const double g=10.0,eps=1e-7;
const int N=100+10,maxn=1000+10,inf=0x3f3f3f;

double x[N],y[N],a[N],l,r;
double dp[(1<<20)+10];
double get(double x0,int i)
{
     double te=atan((r-x[i])/y[i]);
     te=min(te,atan((x0-x[i])/y[i])+a[i]);
     return x[i]+y[i]*tan(te);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout<<setiosflags(ios::fixed)<<setprecision(12);
    int n;
    cin>>n>>l>>r;
    r-=l;
    for(int i=0;i<n;i++)
    {
        cin>>x[i]>>y[i]>>a[i];
        x[i]-=l;
        a[i]=a[i]/180*pi;
    }
    memset(dp,0,sizeof dp);
    for(int i=0;i<(1<<n);i++)
        for(int j=0;j<n;j++)
            if((i&(1<<j))==0)
                dp[(i^(1<<j))]=max(dp[(i^(1<<j))],get(dp[i],j));
    cout<<dp[(1<<n)-1]<<endl;
    return 0;
}
/********************

********************/

时间: 2024-10-08 00:33:56

CodeForces 385 D.Bear and Floodlight 状压DP的相关文章

codeforces 342D Xenia and Dominoes(状压dp+容斥)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud D. Xenia and Dominoes Xenia likes puzzles very much. She is especially fond of the puzzles that consist of domino pieces. Look at the picture that shows one of such puzzles. A puzzle is a 3 ×

Codeforces 385 D Bear and Floodlight

主题链接~~> 做题情绪:时候最后有点蛋疼了,处理点的坐标处理晕了.so~比赛完清醒了一下就AC了. 解题思路: 状态压缩DP ,仅仅有 20 个点.假设安排灯的时候仅仅有顺序不同的问题.全然能够用状态压缩去递推出来,仅仅是处理点的坐标的时候非常麻烦,理清思路就好了. 状态方程: dp [ S | (1 << i ) ]  = max( dp[ S |( 1 << i ) ] , dp[ S ] + W )  , 在状态 S 的情况下再加入 i 点(S 中先前不含 i 点),

Codeforces 678E:Another Sith Tournament 状压DP

odd-even number 题目链接: http://codeforces.com/problemset/problem/678/E 题意: 有n个人打擂台赛,每两个人间都有相对的胜率,主角可以操控比赛顺序,求主角最后获胜的最大概率. 题解: 设dp[i][j]为状态 i (二进制位代表出场选手) j 号选手第一个上场时主角的最大胜率,dp[1][0]=1.0(场上只有主角一个人主角必胜). 状态转移方程dp[i][j]=max(dp[i][j],dp[i^(1<<j)][k]*p[k][

Codeforces 580D Kefa and Dishes(状压DP)

题目大概说要吃掉n个食物里m个,吃掉各个食物都会得到一定的满意度,有些食物如果在某些食物之后吃还会增加满意度,问怎么吃满意度最高. dp[S][i]表示已经吃掉的食物集合是S且刚吃的是第i个食物的最大满意度 ..没什么好说的 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 int val[18],pairs[18][18]; 6 long long d[1<<18][18]; 7 8

Codeforces Gym 100676G Training Camp 状压dp

http://codeforces.com/gym/100676 题目大意是告诉你要修n门课,每门课有一个权值w[i], 在第k天修该课程讲获得k*w[i]的学习点数,给出了课程与先修课程的关系,要修该课程必须修完先修课程.问最多能学到多少点数. 非常简单的一道状压dp(一开始我还误导队友写成两维的去了 T^T); dp[s] : s 的二进制存放的是已经选择的课程,在该状态下的能获得的最大的点数. 这时如果再学一门课程k,将转移到状态ss (s | (1 << k) ) ,能否转移需要判断合

CodeForces 21D Traveling Graph 状压dp+欧拉回路

题目链接:点击打开链接 题意: 给定n个点m条边的无向图 求从1点开始经过每条边至少一次最后回到1点的最小路程 显然就是找一条路径可重复的欧拉回路 思路: 首先对于欧拉回路的结论是:所有点的度数都为偶数 因为所有边至少经过一次,那么可以把题意转换成加最少多少条边使得图满足以上结论 而加的边目的是为了把奇度数转成偶度数,先floyd一下得到任意点间加边的最小花费 dp[i]表示状态i下度数都为偶数的最小花费. 状压dp,把i状态下,所有未选择的点中挑2个奇度数的转移即可. #include <cs

Codeforces 580D-Kefa and Dishes(状压DP)

原题链接:http://codeforces.com/problemset/problem/580/D 题意:在n个数字中有顺序地选择m个数字,每个数字对应有个值ai,每取一个数字答案加上ai,并且存在k个关系:x y c,如果x恰好排在y的前面,那么答案再加上ci的值.输出最大值. 思路:状压dp.dp[i][j]中,i是已经选了若干个数的情况,j是最后一个被选取的数,i从选取1个到m个枚举下去,j从第1个数到第n个数进行枚举就能得到答案. AC代码: 1 #include<iostream>

CodeForces 757D Felicity&#39;s Big Secret Revealed(状压DP)

题意:给定一个01串,一个有效的n切割定义如下:一个横杠代表一次切割,第一条横杠前面的01串不算,最后一条横杠后面的01串不算,将两个横杠中的01串转化成十进制数字,假设这些数字的最大值是MAX且这些数字囊括了1-MAX的所有数字,则称为一次有效切割.求2~n+1次有效切割的切法. 思路: 由于题目要求包含所有1-MAXN的数字,且n<=75,所以MAXN<=20.另dp[i][j]表示第i位前面有一个横杆且存在j这个状态,接着从第i位开始枚举到第j位为下一个横杆的位置,设这两段横杆之间的数字

codeforces 453 B Little Pony and Harmony Chest (状压dp)

题目大意: 需要你构造一个b数组.使得b数组中的所有元素互质. 而且使得b数组与a数组中的每个对应下标元素的差值和最小. 思路分析: 考虑到 a中所有元素都是 0 - 30. 所以b中的元素也只可能在 0 - 59. 因为如果b 选择60的话,结果和1是一样的,而且b序列中 1 可以重复出现很多次. 因为gcd (1,x) = 1.. 所以们首先把2 - 59中的所有素数处理出来,只有17个. 然后状压这些素数因子. dp[i] [s] [0] 表示 递推到第 i 个位置 达到素数因子为s的状态