zoukankan      html  css  js  c++  java
  • HDU 4234 Moving Points

    刚开始做的时候还以为是暴搜,YY了各种剪枝,结果华丽丽的TLE了
     
     
    正解:
     
    状态压缩DP  
    dp[当前走到的点][状态] 
    状态: 第i位表示第i个点有没有被消灭
    转移: 详见代码
    注意: 计算转移cost时要用O(1) 的算法 二分会TLE
     
    代码:
     
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    using namespace std;

    #define for if(0); else for
    const double PI=acos(-1.0);

    struct Point{
        double x,y,vx,vy,t;
        Point(){}
        Point(double x,double y){
            this->x=x;
            this->y=y;
        }
        Point(double x,double y,double d,double v){
            this->x=x;
            this->y=y;
            this->vx=v*cos(d*PI/180.0);
            this->vy=v*sin(d*PI/180.0);
            this->t=0;
        }
        Point go(double t) const{
            Point ret=*this;
            ret.x+=vx*t;
            ret.y+=vy*t;
            return ret;
        }
    };

    int n;
    Point p[16];
    double spd;
    double dp[16][1<<15];
    bool vis[16][1<<15];

    double dis(const Point &a,const Point &b){
        double dx=a.x-b.x;
        double dy=a.y-b.y;
        return sqrt(dx*dx+dy*dy);
    }

    double cost(const Point &a,const Point &b){
        Point ta=Point(b.x-a.x,b.y-a.y);
        Point v=Point(b.vx,b.vy);
        double V=dis(v,Point(0,0));
        double D=dis(ta,Point(0,0));
        double A=V*V-spd*spd;
        double C=D*D;
        double B=-2.0*(ta.x*v.x+ta.y*v.y);
        return (B-sqrt(B*B-4*A*C))/2.0/A;
    }


    int main() {
        setbuf(stdout,NULL);
        while(scanf("%d%lf",&n,&spd) &&(n!=0&&spd!=0)){
            p[0]=Point(0,0,0,0);
            for(int i=1;i<=n;i++){
                double x,y,d,v;
                scanf("%lf%lf%lf%lf",&x,&y,&d,&v);
                p[i]=Point(x,y,d,v);
            }
            memset(vis,0,sizeof(vis));
            vis[0][0]=1;
            for(int stat=1;stat<1<<n;stat++){
                for(int i=1;i<=n;i++){
                    int prev=stat;
                    prev &= ~ ( 1<< (i-1) );
                    if(prev==stat) continue;
                    for(int j=0;j<=n;j++) if(j!=i){
                        if(vis[j][prev]){
                            double val=dp[j][prev]+cost(p[j].go(dp[j][prev]),p[i].go(dp[j][prev]));
                            if(!vis[i][stat]) vis[i][stat]=1,dp[i][stat]=val;
                            else dp[i][stat]=min(dp[i][stat],val);
                        }
                    }
                }
            }
            double ans=dp[1][(1<<n)-1];
            for(int i=1;i<=n;i++) ans=min(ans,dp[i][(1<<n)-1]);
            printf("%.2lf\n",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    腾讯//全排列
    腾讯//全排列
    腾讯//子集
    腾讯//子集
    腾讯///括号生成
    腾讯///括号生成
    腾讯//二叉树的最近公共祖先
    腾讯//二叉树的最近公共祖先
    腾讯//二叉搜索树的最近公共祖先
    腾讯//二叉搜索树的最近公共祖先
  • 原文地址:https://www.cnblogs.com/programCaiCai/p/HDU4324.html
Copyright © 2011-2022 走看看