zoukankan      html  css  js  c++  java
  • [Uva10641]Barisal Stadium(区间dp)

    题意:按照顺时针给出操场的周边点,然后给出周围可以建设照明灯的位置,以及在该位置建设照明灯的代价,照明灯照射的范围与操场的边界相切,现在要求一个最小的花费,要求操场的所有边都被照射到。

    解题关键:预处理每台灯能够覆盖到的范围,然后对环进行dp即可。对环进行dp的方法是枚举起点,覆盖所有点即可。

    注意用叉积的方法处理灯能否照到某条边->某个点。

    $dp[i][j]$表示从第$i$个点到第$j$个点之间的边都被照射到的最小代价,只要有某个等得照射范围有覆盖到$i$,$j$,就可以向外扩展。

    #include<bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const double eps=1e-8;
    const int N=105;  
    const int M=1005;  
    int n,m,dp[N];  
    bool flag[N];
    struct Point{  
        double x,y;  
        Point(double x=0,double y=0) {  
            this->x=x;  
            this->y=y;  
        }
        void read(){  
            scanf("%lf%lf",&x,&y);  
        }
    }p[N],o;
      
    struct node{  
        int l,r,c;
    }q[M];
    
    bool judge(Point p0, Point p1, Point p2) {  
        return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y)<-eps;//叉积判断是否能被照到 
    }
    
    node tra(Point t, int c){  
        node ans;  
        ans.c=c;
        memset(flag,0,sizeof flag);  
        for(int i=0;i<n;i++) if(judge(t,p[i],p[i+1]))  flag[i]=true;
        if (flag[0]&&flag[n-1]){  
            int l=n-1,r=0;
            while(flag[l-1]) l--;  
            while(flag[r+1]) r++;  
            ans.l=l,ans.r=r+n;
        }
        else{  
            int l=0,r=n-1;  
            while(!flag[l]) l++;
            while(!flag[r]) r--;
            ans.l=l,ans.r=r;  
        }
        return ans;  
    }  
      
    bool solve(){  
        int ans=inf; 
        for(int i=0;i<n;i++){  
            fill(dp,dp+2*n+1,inf);
            dp[i]=0;
            for(int j=0;j<n;j++){
                int r=i+j;  
                for(int k=0;k<m;k++){
                    if(q[k].l>r) continue;
                    int now=min(i+n,q[k].r+1);  
                    dp[now]=min(dp[now],dp[r]+q[k].c);  
                }  
            }  
            ans=min(ans,dp[i+n]);
        }
        if(ans==inf) return false;
        printf("%d
    ",ans);
        return true;
    }  
      
    int main(){  
        while(~scanf("%d",&n)&&n){
            for(int i=0;i<n;i++) p[i].read();  
            p[n]=p[0];
            scanf("%d",&m);  
            Point tmp;  
            int c;  
            for(int i=0;i<m;i++){  
                tmp.read();
                scanf("%d",&c);  
                q[i]=tra(tmp,c);  
            }
            if (!solve()) printf("Impossible.
    ");  
        }  
        return 0;  
    }  
  • 相关阅读:
    静态变量的问题
    水晶报表动态表数据显示的问题
    USACO Section 1.1 : Friday the Thirteenth
    USACO Section 1.2 : Transformations
    USACO Section 1.1 : Programming Contest Problem Types
    USACO Section 1.2 : Milking Cows
    USACO Section 1.1 : Greedy Gift Givers
    USACO Section 1.1 : Your Ride Is Here
    USACO Section 1.1 : Broken Necklace
    舍入Table.TransformColumns(Power Query 之 M 语言)
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7808858.html
Copyright © 2011-2022 走看看