DL24 10.6

$T1$:$20$分暴力。直接计算每个点左右所能到达的最大值,因为有些点可能在之后会被填平,所以左右每个点都需要记录并排序。然后$dfs$枚举所有选择填平$k$个点的方案,计算即可。$O(max(C(20,i))n$2$)$

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 #define ll long long
 4 using namespace std;
 5 const int mod = 1e9 + 7;
 6 int n, k, h[30], vis[30], q[30];
 7 ll ans;
 8 struct Max {int maxl[30], maxr[30], maxln[30], maxrn[30];}stu[30];
 9 struct T {int x, num;}t[30];
10 int cmp(T a, T b) {return a.x > b.x;}
11 void solve()
12 {
13     ll sum = 0;
14     for(int i = 1; i <= n; ++i) {h[i] = q[i]; if(vis[i]) h[i] = 0;}
15     for(int i = 1; i <= n; ++i)
16     {
17         int Maxl = 0, Maxr = 0;
18         for(int j = 1; j < i; ++j) if(!vis[stu[i].maxln[j]]) {Maxl = stu[i].maxl[j]; break;};
19         for(int j = 1; j <= n - i; ++j) if(!vis[stu[i].maxrn[j]]) {Maxr = stu[i].maxr[j]; break;}
20         if(h[i] < Maxl && h[i] < Maxr) sum += (min(Maxl, Maxr) - h[i]);
21     }
22     if(sum % 2 == 0) ++ans;
23     return;
24 }
25 void dfs(int x, int num)
26 {
27     if(n - num < k - x) return;
28     if(x > k) {solve(); return;}
29     for(int i = num; i <= n; ++i)
30     {
31         if(!vis[i])
32         {
33             vis[i] = 1;
34             dfs(x + 1, i + 1);
35             vis[i] = 0;
36         }
37     }
38     return;
39 }
40 int main()
41 {
42     freopen("rain.in", "r", stdin), freopen("rain.out", "w", stdout);
43     scanf("%d %d", &n, &k);
44     for(int i = 1; i <= n; ++i) scanf("%d", &h[i]), q[i] = h[i];
45     for(int i = 1; i <= n; ++i)
46     {
47         int z = 0;
48         for(int j = 1; j < i; ++j) t[++z].x = h[j], t[z].num = j;
49         sort(t + 1, t + z + 1, cmp);
50         for(int j = 1; j <= z; ++j) stu[i].maxl[j] = t[j].x, stu[i].maxln[j] = t[j].num;
51         z = 0;
52         for(int j = n; j > i; --j) t[++z].x = h[j], t[z].num = j;
53         sort(t + 1, t + z + 1, cmp);
54         for(int j = 1; j <= z; ++j) stu[i].maxr[j] = t[j].x, stu[i].maxrn[j] = t[j].num;
55     }
56     dfs(1, 1);
57     printf("%lld", ans % mod);
58     return 0;
59 }

$T3$:$40$分暴力。对于每一行的每一块土地,挖掘机可以用钻头进行覆盖,贪心每次覆盖最左边的土地,计算即可。$O(hw$2$)$

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 using namespace std;
 4 int h, w, k, q;
 5 char s[20][100010];
 6 int solve(int d, int l, int r)
 7 {
 8     int ans = 0;
 9     for(int i = 1; i <= d; ++i)
10         for(int j = l; j <= r; ++j)
11             if(s[i][j] == 'X') 
12                 ++ans, j = j + k - 1;
13     return ans;
14 }
15 int main()
16 {
17     freopen("blueshit.in", "r", stdin), freopen("blueshit.out", "w", stdout);
18     scanf("%d %d %d %d", &h, &w, &k, &q);
19     for(int i = 1; i <= h; ++i) scanf("%s", s[i] + 1);
20     for(int i = 1, d, l, r; i <= q; ++i) scanf("%d %d %d", &d, &l, &r), printf("%d\n", solve(d, l, r));
21     return 0;
22 }

$T4$:$20$分暴力,枚举$k$,再枚举$A$和$B$的每一个子串,通过记录$f[k][i][j]$表示长度为$k$且$A$中以$i$开头,$B$中以$j$开头谁获胜进行转移,预处理$f[0][i][j]$。$O(k|A||B|)$

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 using namespace std;
 4 int lx, ly, f[110][110][110], wx, wy, wp, all;
 5 char x[110], y[110];
 6 int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
 7 int main()
 8 {
 9     freopen("game.in", "r", stdin), freopen("game.out", "w", stdout);
10     scanf("%s %s", x + 1, y + 1);
11     lx = strlen(x + 1), ly = strlen(y + 1);
12     for(int i = 1; i <= lx; ++i)
13     {
14         for(int j = 1; j <= ly; ++j)
15         {
16             if(x[i] < y[j]) f[0][i][j] = 1, ++wx;
17             else if(x[i] > y[j]) f[0][i][j] = -1, ++wy;
18             else f[0][i][j] = 0, ++wp;
19         }
20     }
21     all = wx + wy + wp;
22     printf("%d/%d %d/%d %d/%d\n", wx / gcd(wx, all), all / gcd(wx, all), wp / gcd(wp, all), all / gcd(wp, all), wy / gcd(wy, all), all / gcd(wy, all));
23     for(int k = 1; k < min(lx, ly); ++k)
24     {
25         wx = 0, wy = 0, wp = 0;
26         for(int i = 1, j = i + k; i <= lx && j <= lx; ++i, ++j)
27         {
28             for(int s = 1, t = s + k; s <= ly && t <= ly; ++s, ++t)
29             {
30                 if(f[k - 1][i][s] == 1) ++wx, f[k][i][s] = 1;
31                 else if(f[k - 1][i][s] == -1) ++wy, f[k][i][s] = -1;
32                 else
33                 {
34                     if(x[j] < y[t]) ++wx, f[k][i][s] = 1;
35                     else if(x[j] > y[t]) ++wy, f[k][i][s] = -1;
36                     else ++wp, f[k][i][s] = 0;
37                 }
38             }
39         }
40         all = wx + wy + wp;
41         printf("%d/%d %d/%d %d/%d\n", wx / gcd(wx, all), all / gcd(wx, all), wp / gcd(wp, all), all / gcd(wp, all), wy / gcd(wy, all), all / gcd(wy, all));
42     }
43     return 0;
44 }
posted @ 2020-10-06 15:03  louis_11  阅读(77)  评论(0)    收藏  举报