zoukankan      html  css  js  c++  java
  • zoj 3537 区间dp+计算几何

    题意:给定n个点的坐标,先问这些点是否能组成一个凸包,如果是凸包,问用不相交的线来切这个凸包使得凸包只由三角形组成,根据costi, j = |xi + xj| * |yi + yj| % p算切线的费用,问最少的切割费用。

    链接:点我

    题解:点我

    2015-07-20:专题复习

    代码稍微修改了一下,顺便发现题号写错了

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 #include<map>
      8 using namespace std;
      9 #define MOD 1000000007
     10 const int INF=0x3f3f3f3f;
     11 const double eps=1e-5;
     12 typedef long long ll;
     13 #define cl(a) memset(a,0,sizeof(a))
     14 #define ts printf("*****
    ");
     15 const int MAXN=310;
     16 int n,m;
     17 int sgn(double x)
     18 {
     19 if(fabs(x) < eps)return 0;
     20 if(x < 0)return -1;
     21 else return 1;
     22 }
     23 struct Point
     24 {
     25     int x,y;
     26     Point(){}
     27 Point(double _x,double _y)
     28 {
     29 x = _x;y = _y;
     30 }
     31 Point operator -(const Point &b)const
     32 {
     33 return Point(x - b.x,y - b.y);
     34 }
     35 //叉积
     36 double operator ^(const Point &b)const
     37 {
     38 return x*b.y - y*b.x;
     39 }
     40 //点积
     41 double operator *(const Point &b)const
     42 {
     43 return x*b.x + y*b.y;
     44 }
     45 //绕原点旋转角度B(弧度值),后x,y的变化
     46 };
     47 Point list[MAXN];
     48 int Stack[MAXN],top;
     49 double dist(Point a,Point b)
     50 {
     51     return sqrt((a-b)*(a-b));
     52 }
     53 //相对于list[0]的极角排序
     54 bool _cmp(Point p1,Point p2)
     55 {
     56     double tmp=(p1-list[0])^(p2-list[0]);
     57     if(sgn(tmp)>0)return true;
     58     else if(sgn(tmp)==0 && sgn(dist(p1,list[0]) - dist(p2,list[0])) <= 0)
     59     return true;
     60     else return false;
     61 }
     62 void Graham(int n)
     63 {
     64     Point p0;
     65     int k=0;
     66     p0=list[0];
     67     //找最下边的一个点
     68     for(int i=1;i < n;i++)
     69     {
     70         if( (p0.y>list[i].y) || (p0.y==list[i].y && p0.x>list[i].x) )
     71         {
     72             p0=list[i];
     73             k=i;
     74         }
     75     }
     76     swap(list[k],list[0]);
     77     sort(list+1,list+n,_cmp);
     78     if(n==1)
     79     {
     80         top=1;
     81         Stack[0]=0;
     82         return;
     83     }
     84     if(n==2)
     85     {
     86         top=2;
     87         Stack[0]=0;
     88         Stack[1]=1;
     89         return ;
     90     }
     91     Stack[0]=0;
     92     Stack[1]=1;
     93     top=2;
     94     for(int i=2;i < n;i++)
     95     {
     96         while(top>1 && sgn((list[Stack[top-1]]-list[Stack[top-2]])^(list[i]-list[Stack[top-2]])) <= 0)
     97         top--;
     98         Stack[top++]=i;
     99     }
    100 }
    101 int cost[MAXN][MAXN];
    102 int dis(Point p1,Point p2)//计算题目定义的cost
    103 {
    104     return abs(p1.x+p2.x)*abs(p1.y+p2.y)%m;
    105 }
    106 int dp[MAXN][MAXN];
    107 int main()
    108 {
    109     int i,j,k;
    110     #ifndef ONLINE_JUDGE
    111     freopen("1.in","r",stdin);
    112     #endif
    113     while(~scanf("%d%d",&n,&m))
    114     {
    115         for(i=0;i<n;i++)
    116         {
    117             scanf("%d%d",&list[i].x,&list[i].y);
    118         }
    119         Graham(n);
    120         if(top!=n)
    121         {
    122             puts("I can't cut.");
    123             continue;
    124         }
    125         cl(cost);
    126         for(i=0;i<n;i++)
    127             for(j=i+2;j<n;j++)
    128                 cost[i][j]=cost[j][i]=dis(list[i],list[j]);
    129         for(i=0;i<n;i++)
    130         {
    131             for(j=i;j<n;j++)dp[i][j]=INF;
    132             dp[i][(i+1)%n]=0;
    133         }
    134         for(int len=2;len<n;len++)
    135         {
    136             for(i=0;i+len<=n-1;i++)
    137             {
    138                 j=i+len;
    139                 for(k=i+1;k<=j-1;k++)
    140                 {
    141                     dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]);
    142                 }
    143             }
    144         }
    145         /*for(i=n-3;i>=0;i--)
    146         {
    147             for(j=i+2;j<n;j++)
    148             {
    149                 for(k=i+1;k<=j-1;k++)
    150                 {
    151                     dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]);
    152                 }
    153             }
    154         }*/
    155         printf("%d
    ",dp[0][n-1]);
    156     }
    157 }
    View Code
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 #include<map>
      8 using namespace std;
      9 #define MOD 1000000007
     10 const int INF=0x3f3f3f3f;
     11 const double eps=1e-5;
     12 typedef long long ll;
     13 #define cl(a) memset(a,0,sizeof(a))
     14 #define ts printf("*****
    ");
     15 const int MAXN=310;
     16 int n,m;
     17 int sgn(double x)
     18 {
     19 if(fabs(x) < eps)return 0;
     20 if(x < 0)return -1;
     21 else return 1;
     22 }
     23 struct Point
     24 {
     25     int x,y;
     26     Point(){}
     27 Point(double _x,double _y)
     28 {
     29 x = _x;y = _y;
     30 }
     31 Point operator -(const Point &b)const
     32 {
     33 return Point(x - b.x,y - b.y);
     34 }
     35 //叉积
     36 double operator ^(const Point &b)const
     37 {
     38 return x*b.y - y*b.x;
     39 }
     40 //点积
     41 double operator *(const Point &b)const
     42 {
     43 return x*b.x + y*b.y;
     44 }
     45 //绕原点旋转角度B(弧度值),后x,y的变化
     46 };
     47 Point list[MAXN];
     48 int Stack[MAXN],top;
     49 double dist(Point a,Point b)
     50 {
     51     return sqrt((a-b)*(a-b));
     52 }
     53 //相对于list[0]的极角排序
     54 bool _cmp(Point p1,Point p2)
     55 {
     56     double tmp=(p1-list[0])^(p2-list[0]);
     57     if(sgn(tmp)>0)return true;
     58     else if(sgn(tmp)==0 && sgn(dist(p1,list[0]) - dist(p2,list[0])) <= 0)
     59     return true;
     60     else return false;
     61 }
     62 void Graham(int n)
     63 {
     64     Point p0;
     65     int k=0;
     66     p0=list[0];
     67     //找最下边的一个点
     68     for(int i=1;i < n;i++)
     69     {
     70         if( (p0.y>list[i].y) || (p0.y==list[i].y && p0.x>list[i].x) )
     71         {
     72             p0=list[i];
     73             k=i;
     74         }
     75     }
     76     swap(list[k],list[0]);
     77     sort(list+1,list+n,_cmp);
     78     if(n==1)
     79     {
     80         top=1;
     81         Stack[0]=0;
     82         return;
     83     }
     84     if(n==2)
     85     {
     86         top=2;
     87         Stack[0]=0;
     88         Stack[1]=1;
     89         return ;
     90     }
     91     Stack[0]=0;
     92     Stack[1]=1;
     93     top=2;
     94     for(int i=2;i < n;i++)
     95     {
     96         while(top>1 && sgn((list[Stack[top-1]]-list[Stack[top-2]])^(list[i]-list[Stack[top-2]])) <= 0)
     97         top--;
     98         Stack[top++]=i;
     99     }
    100 }
    101 int cost[MAXN][MAXN];
    102 int dis(Point p1,Point p2)//计算题目定义的cost
    103 {
    104     return abs(p1.x+p2.x)*abs(p1.y+p2.y)%m;
    105 }
    106 int dp[MAXN][MAXN];
    107 int main()
    108 {
    109     int i,j,k;
    110     #ifndef ONLINE_JUDGE
    111     freopen("1.in","r",stdin);
    112     #endif
    113     while(~scanf("%d%d",&n,&m))
    114     {
    115         for(i=0;i<n;i++)
    116         {
    117             scanf("%d%d",&list[i].x,&list[i].y);
    118         }
    119         Graham(n);
    120         if(top!=n)
    121         {
    122             puts("I can't cut.");
    123             continue;
    124         }
    125         cl(cost);
    126         for(i=0;i<n;i++)
    127             for(j=i+2;j<n;j++)
    128                 cost[i][j]=cost[j][i]=dis(list[i],list[j]);
    129         for(i=0;i<n;i++)
    130         {
    131             for(j=i;j<n;j++)dp[i][j]=INF;
    132             dp[i][(i+1)%n]=0;
    133         }
    134         for(i=n-3;i>=0;i--)
    135         {
    136             for(j=i+2;j<n;j++)
    137             {
    138                 for(k=i+1;k<=j-1;k++)
    139                 {
    140                     dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]);
    141                 }
    142             }
    143         }
    144         printf("%d
    ",dp[0][n-1]);
    145     }
    146 }
  • 相关阅读:
    极客技术专题【011期】:EasyUI初级教程
    帮助自定义选择框样式的Javascript
    利用HTML5与jQuery技术创建一个简单的自动表单完成
    30个iPhone健康应用帮助你保持身体健康
    如何构建下拉滑动式响应导航菜单
    推荐十款来自极客标签的超棒前端特效[第十三期]
    重新设计网站的10点建议
    创建CSS3警示框渐变动画
    17种新型的响应式开发框架
    使用jQuery创建模态窗口登陆效果
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4507530.html
Copyright © 2011-2022 走看看