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("*****\n");

 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\n",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("*****\n");

 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\n",dp[0][n-1]);

145     }

146 }

 

你可能感兴趣的:(ZOJ)