POLYGON(动态规划)
学校老师布置的一道动规的题目,要求下次上课前AC。周一一放学就回家写,调试了一会儿OK了。在这边记录一下解题的思路和过程,也作为第一篇随笔,就是随便之一写,您也就随便之一看。有问题望你指出,多多包涵。
题目描述如下:
POLYGON
源程序名 POLYGON.??? (PAS,C,CPP)
可执行文件名 POLYGON.EXE
输入文件名 POLYGON.IN
输出文件名 POLYGON.OUT
对于一个多边形来说,在该多边形内任取两点,如果这两点连成的线段落在多边形内,则称这样的多边形为凸多边形。
平面上有N个坐标值为自然数的圆点。顶点数最多凸多边形是指由给定的圆点中的一部分组成的凸多边形,它包含最大可能的顶点数。原点,即坐标内中心(0,0)必须是顶点数最多凸多边形的一个顶点。
编写程序求出这样的凸多边形的最大顶点数。注意一个多边形的连续的边不能是平行的。
输入
输入文件的第一行包含一个自然数N,2≤N≤100,表示给定的圆点数。
下面的N行每行包含两个用空格隔开的自然数X和Y,1≤X≤100,1≤Y≤100,表示一个圆点的坐标值。所有的圆点是不相同的。
输出
输出文件的第一行也是唯一的一行应该包含顶点数最多凸多边形的顶点数。注意结果应不小于3。
样例
POLYGON.IN
8
10 8
3 9
2 8
2 3
9 2
9 10
10 3
8 10
POLYGON.OUT
8
因为接触信息竞赛时间不长,老师对这道题给了两点提示:
第一点大家在下面也都想到了就是按照斜率给点进行排序再处理;
第二点就是关于判断凸多边形的问题,这里用到了向量和矩阵的知识。这里我们不妨假设斜率是按照从小到大的顺序排列。所以判断(x3,y3)就是否可以和已经构成一边的(x1,y1)、(x2,y2)构成凸多边形。(作者数学不是很好,所以推理不是很严谨)即把(x1,y1)、(x2,y2)构成的一边看作以(x1,y1)为起点,(x2,y2)为终点的向量,而点(x3,y3)就是向量外一点,如果这个向量及其延长线逆时针转一个小于180°的角可以碰到(x3,y3)则判定可以加入这个点,然后用行列式求坐标系中三角形的公式就可以得出如果x1(y2-y3)+x2(y3-y1)+x3(y1-y2)>0 则符合条件(也排除了等于0是三点共线的情况)。
最后老师在黑板上随便写下了一个动态转移方程 Fi=max{Fj+1}.
也就是这个公式是我们走了不少弯路。
因为这是一个点到另一个点的动规情况,并不是一个维度就可以描述出来的。所以我想可以这样写方程
第 i 个点到 i 后第 j 个点可以加入构成凸多边形的最多的变数为Fij ,则 Fij=max{ Fki ,1<=k<=i-1}+1 并且j 如果到了最后一个点之后就返回第一个点,这样在最后扫描一边 Fi1 就可以得到结果了。
具体不是很规范的代码如下:
#include<stdio.h>
#include<stdlib.h>
FILE *fin,*fout;
int n,f[][],max=,ans=,y[], x[];
double a[];
void qs(double a[],int x[],int y[],int left,int right){
if(left>=right) return ;
int i=left;
int j=right;
double key=a[left];
int key2=x[left],key3=y[left];
while(i < j)
{
while(i < j && key <= a[j]) j--;
{ a[i] = a[j]; x[i]=x[j];y[i]=y[j];}
while(i < j && key >= a[i]) i++;
{a[j] = a[i]; x[j]=x[i]; y[j]=y[i];}
}
a[i] = key;x[i]=key2;y[i]=key3;
qs(a,x,y,left,i-);
qs(a,x,y,i+,right);
}
int judge(int x1,int y1,int x2,int y2,int x3,int y3){
if((x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))>) return ;
else return ;
}
int main(){
int i,j,t,k;
fin=fopen("polygon.in","r");
fout=fopen("polygon.out","w");
fscanf(fin,"%d",&n);n++;
x[]=;y[]=;
for(i=;i<=n;i++){
fscanf(fin,"%d%d",&x[i],&y[i]);
a[i]=(double)y[i]/x[i];
}
qs(a,x,y,,n);
for(i=;i<=n;i++)
f[][i]=;
for(i=;i<=n;i++)
{
for(j=i+;j<=n+;j++)
{
if(j==n+) t=;
else t=j;
for(k=;k<=i-;k++){
if(judge(x[k],y[k],x[i],y[i],x[t],y[t]))
if(f[k][i]+>f[i][t])
f[i][t]=f[k][i]+;
}
}
}
for(i=;i<=n;i++)
{
if(f[i][]>ans) ans=f[i][];
}
fprintf(fout,"%d\n",ans);
fclose(fin);
fclose(fout);
return ;
}
最后写一点总结性的,算是为以后再看时留下更有用的信息:此题动态规划时前后区间均要扫面全面,才可以使程序实现随时根据最优情况做出调成的功能。
(第一篇草草写完,很激动,吃饭去了)
——励志不做copy王
POLYGON(动态规划)的更多相关文章
- POJ-1179 Polygon (动态规划)
Polygon Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5293 Accepted: 2238 Description P ...
- {POJ}{动态规划}{题目列表}
动态规划与贪心相关: {HDU}{4739}{Zhuge Liang's Mines}{压缩DP} 题意:给定20个点坐标,求最多有多少个不相交(点也不相交)的正方形 思路:背包问题,求出所有的正方形 ...
- poj 1179 Polygon
http://poj.org/problem?id=1179 Polygon Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...
- poj 动态规划题目列表及总结
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- poj动态规划列表
[1]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 13 ...
- POJ 动态规划题目列表
]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 1322 ...
- Largest Rectangle in a Histogram(最大矩形面积,动态规划思想)
Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- poj 动态规划的主题列表和总结
此文转载别人,希望自己可以做完这些题目. 1.POJ动态规划题目列表 easy:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, ...
- poj 1179 $Polygon$(断环成链)
Polygon \(solution:\) upd:还是多讲一下,这道题基本上可以说是一道思维题.一道结论题.一道考验你动态规划基本功是否扎实的题目.因为这道题的数据范围很小,思考一下总能想到断环成链 ...
随机推荐
- 基于FPGA的HDMI显示设计(三)
上一篇:基于FPGA的VGA显示设计(二) 10月10日 ~ 20日期间实习,令我万万没想到的是实习题目是 “便携式高清电视显示屏测试系统原型设计” 也就是 “基于FPGA的视频显示”. 实习要求用 ...
- ZT 父子进程共享文件描述符
转贴自倒霉熊的博客 [linux学习笔记-2]父子进程共享文件描述符 (2009-03-02 23:03:17) 转载▼ 标签: 学习 linux 子进程 文件描述符 杂谈 分类: 学习 #inclu ...
- 郑州集训day1自闭有感
被拉到郑州培训了 考了一上午莫名自闭 帮助慎老师拿到\(rk1\)非常开心 简述一下题目吧 T1.まんふは函数 原题地址 考原题还行 据说是\(Huffman\)树 在成爷爷的再三讲解下,我终于明白了 ...
- (第五场)G max 【数论】
题目链接:https://www.nowcoder.com/acm/contest/143/G 题目描述 Give two positive integer c, n. You need to fin ...
- php 引用变量
什么是引用: 官方给的解释是:用不同的名字访问同一个变量内容. 1.普通的变量 运行之后内存空间变化是这样的: 2.引用变量 运行之后内存变化是这样的: 几乎没有什么变化. 3.使用unset 销毁的 ...
- sql server 语句获取表的描述,主键等等
sql语句添加表,字段的描述 --添加表的描述 --格式如右:execute sp_addextendedproperty 'MS_Description','字段备注信息','user','dbo' ...
- LeetCode15.三数之和 JavaScript
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...
- 并发编程之多线程基础-Thread和Runnable的区别及联系(二)
上篇文章讲述了创建线程的常用方式 本篇主要分析一下Thread和Runnable两种方式创建线程的区别及联系 联系: ▶Thread类实现了Runable接口. ▶都需要重写里面Run方法. 区别: ...
- 序列化表单为json对象,datagrid带额外参提交一次查询 后台用Spring data JPA 实现带条件的分页查询 多表关联查询
查询窗口中可以设置很多查询条件 表单中输入的内容转为datagrid的load方法所需的查询条件向原请求地址再次提出新的查询,将结果显示在datagrid中 转换方法看代码注释 <td cols ...
- IOS NSNotification 通知
一. 先看下官方对NSNotification通知的解释 1. NSNotification 通知 @interface NSNotification : NSObject <NSCopying ...