UVA10641 Barisal Stadium 照亮体育馆
既然要照亮整个体育馆,我们就必须清楚每个光源能照到那些边,毫无头绪
问了老师才知道要用叉积。。。推荐一篇讲叉积讲的非常好的题解https://blog.csdn.net/zsyzClb/article/details/90105535
手玩样例,易知每个光源照到的边一定是连续的,这样就可以进行区间dp了不连续也可以呀。。。
f[i][j]表示照亮断点为i,i+1到j,j+1的边(顶点为n,n+1的边就是n,1这条边)的最小花费
则转移方程为f[i][j]=max(f[i][k]+f[k+1])(i≤k<j)
记得拆环
注意一种特殊情况:
上代码~
1 #include<bits/stdc++.h>
2 using namespace std;
3 const double eps=1e-5;
4 long long n,m;
5 double px[35],py[35];
6 long long book[1005][35];
7 long long f[125][125];
8 long long pre[125][125];
9 void out(int l,int r)
10 {
11 cout<<l<<' '<<r<<' '<<f[l][r]<<endl;
12 if(pre[l][r]==0) return;
13 out(l,pre[l][r]);
14 out(pre[l][r]+1,r);
15 //cout<<pre[l][r]<<endl;
16 }
17 struct node
18 {
19 double x,y;
20 }p[1005];
21 struct lt
22 {
23 long long l,r,v;
24 }q[1005];
25 bool cp(double x,double y,double xx,double yy)
26 {
27 // cout<<x<<' '<<y<<' '<<xx<<' '<<yy<<endl;
28 // cout<<int(x*yy>(y*xx+eps))<<endl;
29 return x*yy>(y*xx+eps);
30 }
31 int main()
32 {
33 // freopen("1.in","r",stdin);
34 // freopen("my.out","w",stdout);
35 while(cin>>n&&n!=0)
36 {
37 for(int i=0;i<=120;i++)
38 for(int j=0;j<=120;j++)
39 f[i][j]=1e18;
40 for(long long i=1;i<=n;i++) cin>>px[i]>>py[i];
41 cin>>m;
42 memset(q,0,sizeof(q));
43 memset(book,0,sizeof(book));
44 for(long long i=1;i<=m;i++) cin>>p[i].x>>p[i].y>>q[i].v;
45 for(long long i=1;i<=m;i++)
46 for(long long j=1;j<=n;j++)
47 {
48 long long pp=j+1;
49 if(pp==n+1) pp=1;
50 if(cp(p[i].x-px[j],p[i].y-py[j],px[pp]-px[j],py[pp]-py[j])) book[i][j]=1;
51 }
52 for(long long i=1;i<=m;i++)
53 {
54 for(long long j=1;j<=n;j++)
55 {
56 if(q[i].l==0&&book[i][j]==1) q[i].l=j;
57 if(book[i][j]==0&&q[i].l!=0&&q[i].r==0) q[i].r=j-1;
58 }
59 if(q[i].r==0&&book[i][n]) q[i].r=n;
60 }
61 for(long long i=1;i<=m;i++)
62 {
63 for(long long j=q[i].r+1;j<=n;j++)
64 {
65 if(book[i][j]==1)
66 {
67 q[i].l=j;
68 q[i].r+=n;
69 break;
70 }
71 }
72 }
73 //for(int i=1;i<=m;i++) cout<<q[i].l<<' '<<q[i].r<<endl;
74 for(long long len=1;len<=n;len++)
75 {
76 for(long long l=1;l<=2*n-1;l++)
77 {
78 long long r=len+l-1;
79 if(r>2*n-1) continue;
80 for(long long i=1;i<=m;i++)
81 {
82 if((q[i].l<=l&&r<=q[i].r)||(q[i].l+n<=l&&r<=q[i].r+n)||(q[i].l-n<=l&&r<=q[i].r-n))
83 {
84 f[l][r]=min(f[l][r],q[i].v);
85 }
86 }
87 }
88 }
89 for(long long len=1;len<=n;len++)
90 {
91 for(long long l=1;l<=2*n-1;l++)
92 {
93 long long r=len+l-1;
94 if(r>2*n-1) continue;
95 for(long long k=l;k<r;k++)
96 {
97 if(f[l][r]>f[l][k]+f[k+1][r])
98 {
99 f[l][r]=f[l][k]+f[k+1][r];
100 pre[l][r]=k;
101 }
102 }
103 }
104 }
105 long long ans=1e18,faq;
106 for(int i=1;i<=n;i++)
107 {
108 if(ans>f[i][i+n-1])
109 {
110 ans=min(ans,f[i][i+n-1]);
111 faq=i;
112 }
113 }
114 if(ans==1e18) cout<<"Impossible."<<endl;
115 else cout<<ans<<endl;
116 // out(faq,faq+n-1);
117 }
118 return 0;
119
120 }