判断输入的点能不能组成凸包(即所有点都要是凸包的顶点) 然后就是求最优三角形划分问题,也就是区间dp 感觉这种区间dp还是记忆化搜索写起来比较方便
记忆化搜索
#include<bits/stdc++.h>
using namespace std ;
const int inf=0x3fffffff ;
int top,s[10024 ];
struct data
{
int x,y;
} p[10024 ],temp;
int corss(data a,data b,data c)
{
return ((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
}
double dis(data a,data b)
{
int t=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
return sqrt (1.0 *t);
}
int cmp(const void *a,const void *b)
{
int m;
data *p1,*p2;
p1=(data *)a;
p2=(data *)b;
m=corss(p[0 ],*p1,*p2);
if (m<0 ) return 1 ;
else if (m==0 &&(dis(p[0 ],*p1)<dis(p[0 ],*p2)))
return 1 ;
else return -1 ;
}
int pt,dp[1024 ][1024 ],c[1024 ][1024 ];
int cost(int i,int j)
{
int t1=p[i].x+p[j].x;
int t2=p[i].y+p[j].y;
if (t1<0 ) t1=-t1;
if (t2<0 ) t2=-t2;
return t1*t2%pt;
}
int get(int s,int t)
{
if (dp[s][t]!=inf) return dp[s][t];
int ans=inf;
for (int k=s+1 ;k<t;k++)
ans=min(ans,get(s,k)+get(k,t)+c[s][k]+c[k][t]);
return dp[s][t]=ans;
}
int main()
{
int n,i,j,k,u,r;
while (~scanf ("%d%d" ,&n,&pt))
{
for (i=0 ; i<n; i++) scanf ("%d%d" ,&p[i].x,&p[i].y);
u=0 ;
for (i=0 ; i<n; i++)
{
if (p[i].y<p[u].y||((p[i].y==p[u].y)&&p[i].x<p[u].x))
u=i;
}
temp=p[u];
p[u]=p[0 ];
p[0 ]=temp;
qsort(&p[1 ],n-1 ,sizeof (int )*2 ,cmp);
for (i=0 ; i<=2 ; i++) s[i]=i;
top=2 ;
for (i=3 ; i<n; i++)
{
while (corss(p[s[top-1 ]],p[s[top]],p[i])<=0 ) top--;
s[++top]=i;
}
if (top!=n-1 )
{
printf ("I can't cut.\n" );
continue ;
}
memset (dp,0 ,sizeof (dp));
for (i=0 ; i<n; i++)
{
for (j=i; j<n; j++)
dp[i][j]=inf;
dp[i][(i+1 )%n]=0 ;
}
memset (c,0 ,sizeof (c));
for (i=0 ; i<n; i++)
for (j=i+2 ; j<n; j++)
c[j][i]=c[i][j]=cost(s[i],s[j]);
printf ("%d\n" ,get(0 ,n-1 ));
}
return 0 ;
}
直接上
#include<bits/stdc++.h>
using namespace std ;
const int inf=0x3f3f3f3f ;
int top,s[10024 ];
struct data
{
int x,y;
} p[10024 ],temp;
int corss(data a,data b,data c)
{
return ((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
}
double dis(data a,data b)
{
int t=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
return sqrt (1.0 *t);
}
int cmp(const void *a,const void *b)
{
double m;
data *p1,*p2;
p1=(data *)a;
p2=(data *)b;
m=corss(p[0 ],*p1,*p2);
if (m<0 ) return 1 ;
else if (m==0 &&(dis(p[0 ],*p1)<dis(p[0 ],*p2)))
return 1 ;
else return -1 ;
}
int pt,dp[1024 ][1024 ],c[1024 ][1024 ];
int cost(int i,int j)
{
int t1=p[i].x+p[j].x;
int t2=p[i].y+p[j].y;
if (t1<0 ) t1=-t1;
if (t2<0 ) t2=-t2;
return t1*t2%pt;
}
int main()
{
int n,i,j,k,u,r;
while (~scanf ("%d%d" ,&n,&pt))
{
for (i=0 ; i<n; i++) scanf ("%d%d" ,&p[i].x,&p[i].y);
u=0 ;
for (i=0 ; i<n; i++)
{
if (p[i].y<p[u].y||((p[i].y==p[u].y)&&p[i].x<p[u].x))
u=i;
}
temp=p[u];
p[u]=p[0 ];
p[0 ]=temp;
qsort(&p[1 ],n-1 ,sizeof (int )*2 ,cmp);
for (i=0 ; i<=2 ; i++) s[i]=i;
top=2 ;
for (i=3 ; i<n; i++)
{
while (corss(p[s[top-1 ]],p[s[top]],p[i])<=0 ) top--;
s[++top]=i;
}
if (top!=n-1 )
{
printf ("I can't cut.\n" );
continue ;
}
memset (dp,0 ,sizeof (dp));
for (i=0 ; i<n; i++)
{
for (j=0 ; j<n; j++)
dp[i][j]=inf;
dp[i][(i+1 )%n]=0 ;
}
memset (c,0 ,sizeof (c));
for (i=0 ; i<n; i++)
for (j=i+2 ; j<n; j++)
c[j][i]=c[i][j]=cost(s[i],s[j]);
for (r=2 ;r<=n;r++)
{
for (i=0 ;i<=n-r;i++)
{
j=i+r-1 ;
for (k=i+1 ;k<=j-1 ;k++)
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+c[i][k]+c[k][j]);
}
}
printf ("%d\n" ,dp[0 ][n-1 ]);
}
return 0 ;
}
直接上
#include<bits/stdc++.h>
using namespace std ;
const int inf=0x3f3f3f3f ;
int top,s[10024 ];
struct data
{
int x,y;
} p[10024 ],temp;
int corss(data a,data b,data c)
{
return ((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
}
double dis(data a,data b)
{
int t=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
return sqrt (1.0 *t);
}
int cmp(const void *a,const void *b)
{
double m;
data *p1,*p2;
p1=(data *)a;
p2=(data *)b;
m=corss(p[0 ],*p1,*p2);
if (m<0 ) return 1 ;
else if (m==0 &&(dis(p[0 ],*p1)<dis(p[0 ],*p2)))
return 1 ;
else return -1 ;
}
int pt,dp[1024 ][1024 ],c[1024 ][1024 ];
int cost(int i,int j)
{
int t1=p[i].x+p[j].x;
int t2=p[i].y+p[j].y;
if (t1<0 ) t1=-t1;
if (t2<0 ) t2=-t2;
return t1*t2%pt;
}
int main()
{
int n,i,j,k,u,r;
while (~scanf ("%d%d" ,&n,&pt))
{
for (i=0 ; i<n; i++) scanf ("%d%d" ,&p[i].x,&p[i].y);
u=0 ;
for (i=0 ; i<n; i++)
{
if (p[i].y<p[u].y||((p[i].y==p[u].y)&&p[i].x<p[u].x))
u=i;
}
temp=p[u];
p[u]=p[0 ];
p[0 ]=temp;
qsort(&p[1 ],n-1 ,sizeof (int )*2 ,cmp);
for (i=0 ; i<=2 ; i++) s[i]=i;
top=2 ;
for (i=3 ; i<n; i++)
{
while (corss(p[s[top-1 ]],p[s[top]],p[i])<=0 ) top--;
s[++top]=i;
}
if (top!=n-1 )
{
printf ("I can't cut.\n" );
continue ;
}
memset (dp,0 ,sizeof (dp));
for (i=0 ; i<n; i++)
{
for (j=0 ; j<n; j++)
dp[i][j]=inf;
dp[i][(i+1 )%n]=0 ;
}
memset (c,0 ,sizeof (c));
for (i=0 ; i<n; i++)
for (j=i+2 ; j<n; j++)
c[j][i]=c[i][j]=cost(s[i],s[j]);
for (i=n-3 ;i>=0 ;i--)
for (j=i+2 ;j<n;j++)
for (k=i+1 ;k<=j-1 ;k++)
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+c[i][k]+c[k][j]);
printf ("%d\n" ,dp[0 ][n-1 ]);
}
return 0 ;
}