群赛 ZOJ3741(dp) ZOJ3911(线段树)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了群赛 ZOJ3741(dp) ZOJ3911(线段树)相关的知识,希望对你有一定的参考价值。
zoj3741
简单dp。wa了两个小时,中间改了好多细节。后来还是不对,参考了别人的代码,发现一个致命问题,初始化的时候,不是每种状态都能直接达到的。初始化成-1。
(题目有个小坑,0<=L<=5, 即使吃药了,也不能到6 )
#include <vector> #include <list> #include <map> #include <set> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cstring> #define pk printf("lalala"); using namespace std; #define PI acos(-1.0) #define EXP exp(1.0) // 自然对数 #define ESP 1E-6 #define clr(x,c) memset(x,c,sizeof(x)) typedef long long ll; const int N = 105; int dp[N][2*N]; int a[N]; void print() { for (int k = 1; k <= 6; ++k) { for (int i = 98; i <= 101; ++i) printf("%d ", dp[k][i]); printf("\n"); } } int main() { int l, n, x, y; while (~scanf("%d%d%d%d", &l, &n, &x, &y)) { clr(dp, -1); for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); } dp[0][100] = 0; for (int i = 1; i <= n; ++i) { for (int j = 100 - y; j <= 100 + x; ++j) { if (j == 100 - y) { if (dp[i - 1][100 + x] == -1) continue; if (0 >= a[i]) dp[i][j] = dp[i - 1][100 + x] + 1; else dp[i][j] = dp[i - 1][100 + x]; } else if (j < 100) { if (dp[i - 1][j - 1] == -1) continue; if (0 >= a[i]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = dp[i - 1][j - 1]; } else if (j == 100 + 1) { if (dp[i - 1][j - 1] == -1 && dp[i - 1][100 - 1] == -1) continue; if ((l + 1 <= 5 && l + 1 >= a[i]) || l >= a[i]) { dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][100 - 1]) + 1; } else { dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][100 - 1]); } } else if (j > 100) { if (dp[i - 1][j - 1] == -1) continue; if ((l + 1 <= 5 && l + 1 >= a[i]) || l >= a[i]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = dp[i - 1][j - 1]; } else { if (dp[i - 1][j] == -1 && dp[i - 1][100 - 1] == -1) continue; if (l >= a[i]) { dp[i][j] = max(dp[i - 1][j], dp[i - 1][100 - 1]) + 1; } else { dp[i][j] = max(dp[i - 1][j], dp[i - 1][100 - 1]); } } } } int ans = 0; for (int i = 100 - y; i <= 100 + x; ++i) { ans = max(ans, dp[n][i]); } //print(); printf("%d\n", ans); } return 0; } /* 3 6 1 2 1 3 4 5 6 4 0 6 3 1 1 0 1 0 1 0 3 6 1 3 3 4 3 3 4 4 3 6 1 2 3 4 3 4 3 4 3 6 1 2 4 5 4 5 4 5 5 6 1 2 6 5 6 4 5 6 5 6 2 3 6 5 6 5 6 5 4 6 1 6 5 5 5 5 5 5 4 6 5 2 5 5 0 0 5 5 4 6 4 4 2 3 3 1 5 */
zoj 3911
线段树区间更新,点更新,区间查询。好久不写,不是很会写了 (尴尬 - -#)
#include <vector> #include <list> #include <map> #include <set> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <numeric> #include <utility> // pair #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cstring> #define pk printf("lalala"); using namespace std; #define PI acos(-1.0) #define EXP exp(1.0) // 自然对数 #define ESP 1E-6 #define clr(x,c) memset(x,c,sizeof(x)) typedef long long ll; const int MAX_N = 10000005; int prime[MAX_N]; bool is_prime[MAX_N]; int sieve(int n) { int p = 0; for (int i = 0; i <= n; ++i) is_prime[i] = true; is_prime[0] = is_prime[1] = false; for (int i = 2; i <= n; ++i) { if (is_prime[i]) { prime[p++] = i; for (int j = 2 * i; j <= n; j += i) is_prime[j] = false; } } return p; } #define lson (o<<1) #define rson (o<<1|1) #define mid ((l+r)>>1) const int N = 100005; int tr[N * 3]; int ans[N * 3]; int v, yl, yr; void pushup(int o) { ans[o] = ans[lson] + ans[rson]; } void build(int o, int l, int r) { if (l == r) { scanf("%d", &tr[o]); if (is_prime[ tr[o] ]) ans[o] = 1; else ans[o] = 0; return ; } build(lson, l, mid); build(rson, mid + 1, r); pushup(o); } void pushdown(int o, int l, int r) { if (tr[o] == 0) return ; tr[lson] = tr[rson] = tr[o]; if (is_prime[ tr[o] ]) { ans[lson] = mid - l + 1; ans[rson] = r - mid; } else { ans[lson] = ans[rson] = 0; } tr[o] = 0; } void add(int o, int l, int r) { if (l == r) { tr[o] += v; if (is_prime[ tr[o] ]) ans[o] = 1; else ans[o] = 0; return ; } pushdown(o, l, r); if (mid >= yl) add(lson, l, mid); else add(rson, mid + 1, r); pushup(o); } void update(int o, int l, int r) { if (yl <= l && yr >= r) { tr[o] = v; if (is_prime[v]) { ans[o] = r - l + 1; } else { ans[o] = 0; } return ; } pushdown(o, l, r); if (yl <= mid) update(lson, l, mid); if (yr > mid) update(rson, mid + 1, r); pushup(o); } int query(int o, int l, int r) { if (yl <= l && yr >= r) return ans[o]; pushdown(o, l, r); int res = 0; if (yl <= mid) res += query(lson, l, mid); if (yr > mid) res += query(rson, mid + 1, r); return res; } int main() { sieve(10000000); int t; scanf("%d", &t); while (t--) { int n, q; scanf("%d%d", &n, &q); clr(tr, 0); build(1, 1, n); while (q--) { char op[4]; scanf("%s", op); if (*op == ‘A‘) { scanf("%d%d", &v, &yl); add(1, 1, n); } else if (*op == ‘R‘) { scanf("%d%d%d", &v, &yl, &yr); update(1, 1, n); } else { scanf("%d%d", &yl, &yr); printf("%d\n", query(1, 1, n)); } } } return 0; }
以上是关于群赛 ZOJ3741(dp) ZOJ3911(线段树)的主要内容,如果未能解决你的问题,请参考以下文章