学校老师布置的一道动规的题目,要求下次上课前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(动态规划)的更多相关文章

  1. POJ-1179 Polygon (动态规划)

    Polygon Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5293 Accepted: 2238 Description P ...

  2. {POJ}{动态规划}{题目列表}

    动态规划与贪心相关: {HDU}{4739}{Zhuge Liang's Mines}{压缩DP} 题意:给定20个点坐标,求最多有多少个不相交(点也不相交)的正方形 思路:背包问题,求出所有的正方形 ...

  3. poj 1179 Polygon

    http://poj.org/problem?id=1179 Polygon Time Limit: 1000MS   Memory Limit: 10000K Total Submissions:  ...

  4. poj 动态规划题目列表及总结

    此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...

  5. poj动态规划列表

    [1]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 13 ...

  6. POJ 动态规划题目列表

    ]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 1322 ...

  7. Largest Rectangle in a Histogram(最大矩形面积,动态规划思想)

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  8. poj 动态规划的主题列表和总结

    此文转载别人,希望自己可以做完这些题目. 1.POJ动态规划题目列表 easy:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, ...

  9. poj 1179 $Polygon$(断环成链)

    Polygon \(solution:\) upd:还是多讲一下,这道题基本上可以说是一道思维题.一道结论题.一道考验你动态规划基本功是否扎实的题目.因为这道题的数据范围很小,思考一下总能想到断环成链 ...

随机推荐

  1. Linux --远程访问控制

    1.SSH服务端 修改配置文件 vi /etc/ssh/sshd_config 监听选项 port 22 //监听端口地址 ListenAddress 192.168.1.50 //监听地址为本机地址 ...

  2. Oracle日志组添加冗余文件和日志组

    rac中需要指定thread添加日志组RAC:alter database add logfile thread 1 group 1('+DATA/irac/redo01_1.log','+DATA/ ...

  3. 数据结构与算法分析java——线性表3 (LinkedList)

    1. LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表.它也可以被当作堆栈.队列或双端队列进行操作.LinkedList 实现 Lis ...

  4. Android(java)学习笔记19:Java中InetAddress类概述和使用

    1. 要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接受数据的计算机和识别发送的计算机. 在TCP/IP协议中,这个标识号就是IP地址. 那么,我们如果获取和 ...

  5. 【LOJ6041】「雅礼集训 2017 Day7」事情的相似度(用LCT维护SAM的parent树)

    点此看题面 大致题意: 给你一个\(01\)串,每次询问前缀编号在一段区间内的两个前缀的最长公共后缀的长度. 离线存储询问 考虑将询问离线,按右端点大小用邻接表存下来(直接排序当然也可以啦). 这样的 ...

  6. 多层感知机训练minist数据集

    MLP .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1p ...

  7. C#位数不足补零

    C#位数不足补零:int i=10;方法1:Console.WriteLine(i.ToString("D5"));方法2:Console.WriteLine(i.ToString ...

  8. oracle序列中cache和nocache

    首先我这篇博客的内容是我不知道oracle里的 cache 是什么,结果越查越多... "序列的cache通常为 20,但在需要依据序列值判断创建的先后顺序时必须是 NOCACHE" ...

  9. 02_Linux 终端命令格式

    01. 终端命令格式 command [-options] [parameter] 说明: command:命令名,相应功能的英文单词或单词的缩写 [-options]:选项,可用来对命令进行控制,也 ...

  10. EntityFramework Code-First教程(一)

    前言:学习了EF框架这么久,还没有好好总结一番,正好遇到一国外的网站,发现不错,随即翻译过来,一是让自己复习一遍,二是供广大初学者学习,翻译过程中加入了一些自己的理解,如有错误,还请指出,多谢多谢.好 ...