See \ ("L min" \), it is easy to think of the two-point answer, then the key to this problem is how to quickly test
First, if the order of operations has been specified, we can solve the \ (O (n) \) Greedy
But to enumerate the order, the complexity is the factorial level, and obviously the star
So consider \ (dp\), I start of the \ (dp\) state:\ (dp[i][j]\) to kill before \ (i\) \ (fa\) altar, with \ (j\ ) the minimum number of green lights at the time of the red light
Find the transfer some trouble, and because the time is not enough, I am random operation order + greedy \ (100\) times (cheat to \ (60\) points)
The solution:
\ (Dp[i][j] Indicates the maximum number of consecutive altars to destroy starting from 1 with the I-\color{green}{green-light} and J-Times \color{red}{Red)
Transfer is
\[dp[i][j]=p[dp[i-1][j]+1]+q[dp[i][j-1]+1]\]
where \ (p[k]\) indicates how many altars are in the right \ (l\) length from the beginning of the k\ , and\ (q[k]\) represents the beginning of the right from the first (k\) altar (2l\) length of the number of altars, can be preprocessed before \ (dp\)
\ (60\) sub- random algorithm:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include < Cstdio> #include <ctime>using namespace std;const int n=2010;int n,r,g,a[n];inline bool Check (int l) {int t=100; while (t--) {int tot1=0,tot2=0,dr=0; for (int i=1;i<=n;i++) {if (A[I]<DR) continue; if (rand ()%2| | TOT2==G) &&tot1!=r) {dr=a[i]+l-1; ++tot1; if (Dr>a[n]) return 1; } else if (tot2!=g) {dr=a[i]+l+l-1; ++tot2; if (Dr>a[n]) return 1; } else break; } if (Dr>a[n]) return 1; } return 0;} int main () {Srand (19260817+time (NULL)); Freopen ("Light.in", "R", stdin); Freopen ("Light.out", "w", stdout); scanf ("%d%d%d", &n,&r,&g); if (r+g>=n) {puts ("1"); return 0; } for (int i=1;i<=n;++i) scanf ("%d", &a[i]); Sort (a+1,a+1+n); int l=1,r=1000000000; while (l<r) {int mid= (L+R) >>1; if (check (mid)) R=mid; else l=mid+1; } printf ("%d\n", L); Fclose (stdin); Fclose (stdout); return 0;}
\ (100\) sub-code
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio>using namespace STD; #define N 2010#define Reset (a) memset (A,0,sizeof (a)) int n,r,g,a[n],dp[n][n];int p[n],q[n];bool Check (int L) {Reset ( P), Reset (Q), reset (DP); for (int i=1;i<=n;i++) {int j=i; while (a[j]<=a[i]+l-1&&j<=n) ++j; P[i]=j-1; while (a[j]<=a[i]+l+l-1&&j<=n) ++j; Q[i]=j-1; } p[n+1]=q[n+1]=n; for (int i=0;i<=r;i++) for (int j=0;j<=g;j++) {if (i) Dp[i][j]=max (dp[i][j],p[dp[i-1][j]+1]); if (j) Dp[i][j]=max (Dp[i][j],q[dp[i][j-1]+1]); } return dp[r][g]==n;} int main () {freopen ("light.in", "R", stdin); Freopen ("Light.out", "w", stdout); scanf ("%d%d%d", &n,&r,&g); if (r+g>=n) {puts ("1"); return 0; } for (int i=1;i<=n;i++) scanf ("%d", &a[i]); Sort (a+1,a+1+n); int l=1,r=1e9; while (l<r) {int mid= (L+R) >>1; if (cheCK (mid)) R=mid; else l=mid+1; } printf ("%d\n", L); Fclose (stdin); Fclose (stdout); return 0;}
"On-campus simulation" Divine Light