1. 程式人生 > >CodeForces 385 D.Bear and Floodlight 狀壓DP

CodeForces 385 D.Bear and Floodlight 狀壓DP

狀態 isp end log opened closed 位置 lag ***

枚舉燈的所有可能狀態(亮或者不亮)(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; } /******************** ********************/
View Code

CodeForces 385 D.Bear and Floodlight 狀壓DP