zoj 3735 dp+计算几何

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

链接:点我

题解:点我

  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 }
时间: 2024-08-08 14:16:22

zoj 3735 dp+计算几何的相关文章

zoj 3735 概率dp

Josephina and RPG Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A role-playing game (RPG and sometimes roleplaying game) is a game in which players assume the roles of characters in a fictional setting. Players take responsibil

DP ZOJ 3735 Josephina and RPG

题目传送门 题意:告诉你C(m,3)个队伍相互之间的胜率,然后要你依次对战n个AI队伍,首先任选一种队伍,然后战胜一个AI后可以选择替换成AI的队伍,也可以不换,问你最后最大的胜率是多少. 分析:dp[i][j][0/1] 表示第i个AI,用j的id去攻打,此j可以是上一个状态交换AI的id而来也可以不是,状态转移方程: dp[i][j][0] = max (dp[i-1][j][0], dp[i-1][j][1]) * p[j][a[i]]; if (i > 1) dp[i][a[i-1]][

ZOJ - 2402 DP方案数

题意:给出m,序列第i位是第i-1位的至少2倍大,的求长度为n且每一位范围均在1-m的序列方案数 对求方案数做不到信手拈来的感觉,需要加强 用简单的预处理和最优子结构能优化到很不错的效率了 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<stri

ZOJ 3603 DP LCS

已经5年没有做OJ了, 曾经沧海难为水,除去巫山不是云" 准备每周刷1-2题! 题目大意:给出N个字符串,且各个字符串都包含唯一的字母,即不存在"ABCA"(A重复了),而"AFDSG"是正确的.                  求出N个字符串的公共字母. 最后,按照字典序输出. 分     析:首先对各个字符串进行字典序排序,然后求所有的LCS,做法是两两相求即可.N个字符串,总共求N-1次LCS,就得到最后的结果了. 代     码: //http:

ZOJ 3632 ----dp+优先队列

上个礼拜学长讲了优先队列的说.... emmmmmm.... 看着题解敲了一题...先m下. #include<cstring> #include<algorithm> #include<iostream> #include<cmath> #include<cstdio> #include<queue> using namespace std; struct gua { long long v,d; bool operator <

[ZOJ 1010] Area (计算几何)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1010 题目大意:给你n个点,问你顺次连线能否连成多边形?如果能,就输出多边形面积. 面积用向量的叉积去算.然后能否连成多边形就是看这条线跟之前的线有没有交点. 这些在大白书上都有板子.. 代码: 1 #include <cstdio> 2 #include <cstdlib> 3 #include <string> 4 #include

ACM模板

目录 语法 c++ java 动态规划 多重背包 最长不下降子序列LIS 计算几何 向量(结构体) 判断两条线段是否相交 曼哈顿距离.切比雪夫距离 Pick定理 二维凸包 点是否在线段上 多边形面积 多边形的面积重心 三维向量(结构体) 三维凸包 数据结构 ST表 单调队列MQ 树状数组BIT 超级树状数组SPBIT 线段树ST 指针版线段树ST 带内存池指针版线段树ST 并查集DSU 左偏树LLT zkw线段树 多关键字堆 双头优先队列 数学 唯一分解 线性递推二项式系数 单个欧拉函数 编码与

待更新算法

网络流 最大流和最小费用最大流原理 上下界网络流 模拟费用流 网络流建模总结 带花树 树 树上倍增 树链剖分 点分治 基环树 DP 概率期望dp 单调队列dp 状压dp 斜率优化dp 计算几何 模板 半平面交 好题 数据结构 线段树高级应用 可持久化线段树 Treap Splay 可持久化平衡树 树套树 分块 莫队 数学 多项式 生成函数 斯特林数 FWT min_25 筛 二次剩余 线性递推 线性基 线性代数 线性规划 群论 字符串 KMP,Z-algorithm,Manacher SA SA

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an