因爲這道題的數據特別小(n<=100),因此咱們能夠考慮較爲暴力的作法。
首先擴倍,因爲是按逆時針順序給出各個樹樁所在的座標,因此。。。是爲了後面的方便。。無所謂了。
咱們先預處理t[i][j][k]表示以i,j,k爲頂點的三角形是否存在即(三角形裏不存在毒藥),若存在t[i][j][k]=面積,若不存在爲0;
咱們先考慮如何求t;咱們首先能夠對於任何一個三角形能夠把其分爲如下兩種c++
分別記錄一下三條線的y=kx+b;而後暴力掃一遍m,而後分類討論(以第二高的點劃分而後,分上下討論)看一下三角形裏有沒有毒,如有return0;else return S=sqrt(q(q-a)(q-b)(q-c)); 。。。。。大家有更好的方法就。。。別打擊我。
這裏理論來講應該是O(n^4)的,可能數據水了,或跑不滿剪了許多。spa
而後設f[i][j]表示i必選以j爲結尾i--->j中可劃分的最大值(從i開始逆時針到j),咱們枚舉i,而後逆時針枚舉j,每次從i<k<j,中選出k來轉移,轉移顯然;分f[i][j]=max{f[i][j],f[i][k]+t[i][k][j]}不過這裏要特判一下,毒藥剛好在兩個三角形邊界上的狀況。例如:code
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct nup{int x,y;}a[301],b[101]; int i,j,n,m,bz[201]; double t[202][202][202],ans,ans1,ans2,k,l,r,z,f[211][211]; void in(double &k,double &z,int a,int b,int a1,int b1) { if(b==b1){k=0,z=b;return;} a-=a1;b-=b1;k=a*1.0/b;z=a1-k*b1; } int abss(int x){return(x>0?x:-x);} double pd(int x,int y,int x1,int y1,int x2,int y2) { if(y<y1){swap(x,x1);swap(y,y1);}if(y<y2){swap(x,x2);swap(y,y2);} if(x1>x2){swap(x1,x2);swap(y1,y2);} double l,k,r,l1,k1,r1,l2,k2,r2,z,z1,z2;//l=kr+z; in(k,z,y,x,y1,x1); in(k1,z1,y,x,y2,x2); in(k2,z2,y1,x1,y2,x2); if(y1>y2) { for(int i=1;i<=m;i++) { if(b[i].y<=y&&b[i].y>=y1) { double xx=(b[i].y-z)*1.0/k;double xx1=(b[i].y-z1)*1.0/k1; if(x==x1) xx=x1;if(x==x2)xx1=x;if(xx>xx1) swap(xx,xx1); if(b[i].x>=xx&&b[i].x<=xx1) return 0; } else if(b[i].y<=y1&&b[i].y>=y2) { double xx=(b[i].y-z2)*1.0/k2;double xx1=(b[i].y-z1)*1.0/k1; if(x1==x2) xx=x1;if(x2==x) xx1=x;if(xx>xx1) swap(xx,xx1); if(b[i].x>=xx&&b[i].x<=xx1) return 0; } } } else { for(int i=1;i<=m;i++) { if(b[i].y<=y&&b[i].y>=y2) { double xx=(b[i].y-z)*1.0/k;double xx1=(b[i].y-z1)*1.0/k1; if(x==x1) xx=x;if(x2==x) xx1=x;if(xx>xx1) swap(xx,xx1); if(b[i].x>=xx&&b[i].x<=xx1) return 0; } else if(b[i].y<=y2&&b[i].y>=y1) { double xx=(b[i].y-z2)*1.0/k2;double xx1=(b[i].y-z)*1.0/k; if(x==x1) xx=x;if(x2==x1) xx1=x1;if(xx>xx1) swap(xx,xx1); if(b[i].x>=xx&&b[i].x<=xx1) return 0; } } } double s,s2,s1; s=sqrt(abss(x-x1)*abss(x-x1)+abss(y-y1)*abss(y-y1)); s1=sqrt(abss(x-x2)*abss(x-x2)+abss(y-y2)*abss(y-y2)); s2=sqrt(abss(x2-x1)*abss(x2-x1)+abss(y2-y1)*abss(y2-y1)); double p=(s+s1+s2)*1.0/2; double res=sqrt(p*(p-s)*(p-s1)*(p-s2)); return res; } double max1(double x,double y){return(x>y?x:y);} int main() { //freopen("a.in","r",stdin); scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y),a[i].x+=10000,a[i].y+=10000,a[n+i].x=a[i].x,a[n+i].y=a[i].y; scanf("%d",&m); for(i=1;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y),b[i].x+=10000,b[i].y+=10000; for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j) for(int kk=1;kk<=n;kk++) if(kk!=i&&kk!=j) { t[i][j][kk]=pd(a[i].x,a[i].y,a[j].x,a[j].y,a[kk].x,a[kk].y); t[i+n][j][kk]=t[i][j+n][kk]=t[i][j][kk+n]=t[i+n][j+n][kk]=t[i+n][j][kk+n]=t[i][j+n][kk+n]=t[i+n][j+n][kk+n]=t[i][j][kk]; } for(i=1;i<=n;i++) { for(j=i+1;j<i+n;j++) { for(int kk=i+1;kk<j;kk++) { if(t[i][kk][j]!=0)f[i][j]=max1(f[i][j],f[i][kk]+t[i][kk][j]); } ans2=max1(ans2,f[i][j]); } } if(ans2!=0)printf("%.2lf",ans2);else printf("die"); }
這是AC的blog
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct nup{int x,y;}a[301],b[101]; int i,j,n,m,bz[201]; double t[202][202][202],ans,ans1,ans2,k,l,r,z,f[211][211]; void in(double &k,double &z,int a,int b,int a1,int b1) { if(b==b1){k=0,z=b;return;} a-=a1;b-=b1;k=a*1.0/b;z=a1-k*b1; } int abss(int x){return(x>0?x:-x);} double pd(int x,int y,int x1,int y1,int x2,int y2) { if(y<y1){swap(x,x1);swap(y,y1);}if(y<y2){swap(x,x2);swap(y,y2);} if(x1>x2){swap(x1,x2);swap(y1,y2);} double l,k,r,l1,k1,r1,l2,k2,r2,z,z1,z2;//l=kr+z; in(k,z,y,x,y1,x1); in(k1,z1,y,x,y2,x2); in(k2,z2,y1,x1,y2,x2); if(y1>y2) { for(int i=1;i<=m;i++) { if(b[i].y<=y&&b[i].y>=y1) { double xx=(b[i].y-z)*1.0/k;double xx1=(b[i].y-z1)*1.0/k1; if(x==x1) xx=x1;if(x==x2)xx1=x;if(xx>xx1) swap(xx,xx1); if(b[i].x>xx&&b[i].x<xx1) return 0; } else if(b[i].y<=y1&&b[i].y>=y2) { double xx=(b[i].y-z2)*1.0/k2;double xx1=(b[i].y-z1)*1.0/k1; if(x1==x2) xx=x1;if(x2==x) xx1=x;if(xx>xx1) swap(xx,xx1); if(b[i].x>xx&&b[i].x<xx1) return 0; } } } else { for(int i=1;i<=m;i++) { if(b[i].y<=y&&b[i].y>=y2) { double xx=(b[i].y-z)*1.0/k;double xx1=(b[i].y-z1)*1.0/k1; if(x==x1) xx=x;if(x2==x) xx1=x;if(xx>xx1) swap(xx,xx1); if(b[i].x>xx&&b[i].x<xx1) return 0; } else if(b[i].y<=y2&&b[i].y>=y1) { double xx=(b[i].y-z2)*1.0/k2;double xx1=(b[i].y-z)*1.0/k; if(x==x1) xx=x;if(x2==x1) xx1=x1;if(xx>xx1) swap(xx,xx1); if(b[i].x>xx&&b[i].x<xx1) return 0; } } } double s,s2,s1; s=sqrt(abss(x-x1)*abss(x-x1)+abss(y-y1)*abss(y-y1)); s1=sqrt(abss(x-x2)*abss(x-x2)+abss(y-y2)*abss(y-y2)); s2=sqrt(abss(x2-x1)*abss(x2-x1)+abss(y2-y1)*abss(y2-y1)); double p=(s+s1+s2)*1.0/2; double res=sqrt(p*(p-s)*(p-s1)*(p-s2)); return res; } double max1(double x,double y){return(x>y?x:y);} int ppd(int x,int y,int x1,int y1) { for(int i=1;i<=m;i++){if(min(x,x1)<b[i].x&&b[i].x<max(x,x1)&&b[i].y<max(y,y1)&&min(y,y1)<b[i].y) return 0;} return 1; } int main() { //freopen("a.in","r",stdin); scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y),a[i].x+=10000,a[i].y+=10000,a[n+i].x=a[i].x,a[n+i].y=a[i].y; scanf("%d",&m); for(i=1;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y),b[i].x+=10000,b[i].y+=10000; for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j) for(int kk=1;kk<=n;kk++) if(kk!=i&&kk!=j) { t[i][j][kk]=pd(a[i].x,a[i].y,a[j].x,a[j].y,a[kk].x,a[kk].y); t[i+n][j][kk]=t[i][j+n][kk]=t[i][j][kk+n]=t[i+n][j+n][kk]=t[i+n][j][kk+n]=t[i][j+n][kk+n]=t[i+n][j+n][kk+n]=t[i][j][kk]; } for(i=1;i<=n;i++) { for(j=i+1;j<i+n;j++) { for(int kk=i+1;kk<j;kk++) { if(t[i][kk][j]!=0&&ppd(a[i].x,a[i].y,a[kk].x,a[kk].y)==1) { if(f[i][kk]+t[i][kk][j]>f[i][j])f[i][j]=f[i][kk]+t[i][kk][j]; } } ans2=max1(ans2,f[i][j]); } } if(ans2!=0)printf("%.2lf",ans2);else printf("die"); }
這是加判斷WA的string