codeforces-1132 (div2)
A.发现b的个数没有意义,a不等于d一定不可行,c不管多少都算一个,如果只有c没有ad也不可行
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 110; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int main(){LL a,b,c,d;scanf("%lld%lld%lld%lld",&a,&b,&c,&d);c = min(c,1ll);if((!a & !d) && c) puts("0");else if(a != d) puts("0");else puts("1");return 0; }
A
B.显然求出所有的和,排序之后,查询的时候减去K大的值就可以了。
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 3e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; LL a[maxn]; bool cmp(LL a,LL b){return a > b; } int main(){Sca(N);LL sum = 0;for(int i = 1; i <= N; i ++){Scl(a[i]);sum += a[i];} sort(a + 1,a + 1 + N,cmp);int q = read();while(q--){int t = read();printf("%lld\n",sum - a[t]);}return 0; }
B
C.显然可以先算出每个编号的墙被刷的数量以及全刷的话刷的总数,然后枚举两面不刷的墙,减去他们的贡献即可。
唯一的问题在于O(1)求出两面墙不刷之后刷不上东西的墙,用两个前缀和分别维护只刷了一发的墙和只刷了两发的墙,分类讨论即可。
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 5010; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn]; PII P[maxn]; int pre1[maxn],pre2[maxn]; bool cmp(PII a,PII b){return a.fi < b.fi; } int main(){Sca2(N,M);for(int i = 1; i <= M ; i ++){int l = read(),r = read();P[i].fi = l,P[i].se = r;for(int j = l; j <= r; j ++) a[j]++;}int ans = 0,sum = 0;;for(int i = 1; i <= N ; i ++){pre1[i] = pre1[i - 1]; pre2[i] = pre2[i - 1];if(a[i] == 1) pre1[i]++;if(a[i] == 2) pre2[i]++;if(a[i]) sum++;}sort(P + 1,P + 1 + M,cmp);for(int i = 1; i <= M ; i ++){for(int j = i + 1; j <= M ; j ++){int flag = 0;if(P[i].se < P[j].fi){flag = pre1[P[i].se] - pre1[P[i].fi - 1] + pre1[P[j].se] - pre1[P[j].fi - 1];}else if(P[j].se < P[i].se){flag = pre2[P[j].se] - pre2[P[j].fi - 1] + pre1[P[j].fi - 1] - pre1[P[i].fi - 1] + pre1[P[i].se] - pre1[P[j].se]; }else{flag = pre1[P[j].fi - 1] - pre1[P[i].fi - 1] + pre2[P[i].se] - pre2[P[j].fi - 1] + pre1[P[j].se] - pre1[P[i].se];}ans = max(ans,sum - flag);}}Pri(ans);return 0; }
C
D.二分 + check,check里面一个优先队列的小贪心,时间复杂度O(n * (logn) * (logn) )
结果竟然TLE了,一度想找O(n)的check但是因为菜放弃了。
后来发现是在堆比较函数里,形如a.a / a.b < b.a / b.b这样的操作会提高计算的常数,需要提前计算好答案在比较
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; LL read(){LL x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 2e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; struct Node{LL a,b,day;Node(){}Node(LL a,LL b,LL day):a(a),b(b),day(day){}inline friend bool operator < (Node a,Node b){return a.day > b.day;} }node[maxn]; inline bool check(LL x){priority_queue<Node>Q;for(register int i = 1; i <= N ; i ++) Q.push(node[i]);for(register int i = 1; i < K ;i ++){Node u = Q.top(); Q.pop();u.a += x; u.day = u.a / u.b;Q.push(u);if(Q.top().day < i) return false;}return true; } LL solve(){LL l = 0,r = 1ll * K * 1e7 + K;LL ans = -1;while(l <= r){LL m = l + r >> 1;if(check(m)){r = m - 1;ans = m;}else{l = m + 1;}}return ans; } inline bool cmp(Node a,Node b){return a.a / a.b < b.a / b.b; } int main(){Sca2(N,K);for(register int i = 1; i <= N ; i ++) node[i].a = read();for(register int i = 1; i <= N ; i ++){node[i].b = read();node[i].day = node[i].a / node[i].b;} sort(node + 1,node + 1 + N,cmp);Prl(solve());return 0; }
D
E.感觉像熟悉的背包问题,但是物品的数量和背包的容量大的夸张,所以需要用其他的方法。
对于数量很多这个情况,可以考虑像背包的二进制优化一样,变为很多更大的小物品并且不影响可以组成的容量种类。
由于背包的容量很大,所以从寻常的迭代查找变成了dfs + 剪枝搜寻的方法,用dfs(i,j)表示当前容量为i并且用到了前j个物品,map<pair<int,LL>,bool>作为vis标记去重之后,再用维护一个物品体积的后缀和方便dfs结束。
虽然这还是TLE了,但是我把所有物品体积从大到小sort了一发就过了
(看了题解似乎有更科学简单的做法?嗯???)
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 2e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; LL W; map<LL,LL>P; LL S[maxn],pre[maxn],ans; int top; map<pair<LL,int>,bool>vis; bool cmp2(LL a,LL b){return a > b; } void dfs(LL t,int p){if(vis[mp(t,p)]) return; vis[mp(t,p)] = 1;if(p == top){ans = max(ans,t);return;}if(t + pre[p + 1] <= W){ans = max(ans,t + pre[p + 1]);return;}if(t + S[p + 1] <= W) dfs(t + S[p + 1],p + 1);dfs(t,p + 1); } int main(){Scl(W);top = 0;priority_queue<LL,vector<LL>,greater<LL> >Q;for(int i = 1; i <= 8; i ++){LL x; Scl(x); P[i] = x;if(x) Q.push(i);}while(!Q.empty()){LL u = Q.top(); Q.pop();LL n = P[u] * u;P[u] = 0;LL now = u;while(n >= now){P[now]++;if(P[now] == 1 && now > u) Q.push(now);n -= now;now <<= 1;}P[n]++;if(n > u && P[n] == 1) Q.push(n);while(P[u]--) S[++top] = u;}sort(S + 1,S + 1 + top,cmp2);for(int i = top; i >= 1; i --){pre[i] = S[i] + pre[i + 1];}dfs(0,0);Prl(ans);return 0; }
E
F.感觉很像区间dp的一道题,实际上确实是区间dp,比较常规的dp[l][r]维护区间内的操作次数最小值。
比较麻烦的是区间的更新,很显然扩展的时候如果扩展出去的恰好和两端相等就不需要增加操作次数。
其次如果两端相等,可以从用中间len - 2长度区间 + 1的次数更新。
当然少不了长区间由左区间合并右区间的操作,显然如果交界处相等,更新答案是两者相加的答案 - 1
到了这一步事实上还过不了第一个样例abaca
需要增加一步,如果l,r之间有一个元素str[i]和str[r]相等,答案更新dp[l][i] + dp[i + 1][r - 1] + dp[r][r] - 1;
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 510; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; char str[maxn]; int dp[maxn][maxn]; int main(){Sca(N);scanf("%s",str + 1);for(int i = 1; i <= N ; i ++) dp[i][i] = 1;for(int len = 2; len <= N ; len++){for(int l = 1; l + len - 1 <= N; l ++){int r = l + len - 1;dp[l][r] = INF;if(str[r] == str[r - 1]) dp[l][r] = min(dp[l][r],dp[l][r - 1]);else dp[l][r] = min(dp[l][r],dp[l][r - 1] + 1);if(str[l] == str[l + 1]) dp[l][r] = min(dp[l][r],dp[l + 1][r]);else dp[l][r] = min(dp[l][r],dp[l + 1][r] + 1);if(str[l] == str[r]) dp[l][r] = min(dp[l][r],dp[l + 1][r - 1] + 1);for(int k = l; k < r; k ++){if(str[k] == str[k + 1]) dp[l][r] = min(dp[l][r],dp[l][k] + dp[k + 1][r] - 1);else dp[l][r] = min(dp[l][r],dp[l][k] + dp[k + 1][r]);if(str[k] == str[r]) dp[l][r] = min(dp[l][r],dp[l][k] + dp[k + 1][r - 1]);}}}Pri(dp[1][N]);return 0; }
F
G.题意不是很容易懂,反正就是求所有K长度区间内的最长贪心子序列,最长贪心子序列的定义是每个元素后接所有第一个比他大的元素。
显然dp[i]表示从i出发的最长贪心子序列。手动模拟一下更新的样例,会发现在j位置更新,就是将k + 1 ~ j 位置的dp[i]全部++;k是左边第一个dp[k]大于等于dp[j]的位置。
那就线段树维护几个区间最大值,再区间更新一下就好了。
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 1e6 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn]; struct Tree{int l,r,lazy;int Max,dp; }tree[maxn << 2]; void Build(int t,int l,int r){tree[t].l = l; tree[t].r = r;tree[t].lazy = 0;if(l == r){tree[t].Max = a[l];tree[t].dp = 1;return;}int m = l + r >> 1;Build(t << 1,l,m); Build(t << 1 | 1,m + 1,r);tree[t].dp = max(tree[t << 1].dp,tree[t << 1 | 1].dp);tree[t].Max = max(tree[t << 1].Max,tree[t << 1 | 1].Max); } int query(int t,int l,int r,int p){if(tree[t].l == tree[t].r){if(tree[t].Max < p) return 0;return tree[t].l;}if(l <= tree[t].l && tree[t].r <= r){if(tree[t << 1 | 1].Max >= p) return query(t << 1 | 1,l,r,p);else return query(t << 1,l,r,p);}int m = (tree[t].l + tree[t].r) >> 1;if(r <= m) return query(t << 1,l,r,p);else if(l > m) return query(t << 1 | 1,l,r,p);else{int ans = query(t << 1 | 1,m + 1,r,p);if(ans) return ans;return query(t << 1,l,m,p);} } void Pushdown(int t){if(tree[t].lazy){tree[t << 1].lazy += tree[t].lazy;tree[t << 1 | 1].lazy += tree[t].lazy;tree[t << 1].dp += tree[t].lazy;tree[t << 1 | 1].dp += tree[t].lazy;tree[t].lazy = 0;} } void update(int t,int l,int r){if(l <= tree[t].l && tree[t].r <= r){tree[t].lazy++;tree[t].dp++;return ;}Pushdown(t);int m = (tree[t].l + tree[t].r) >> 1;if(r <= m) update(t << 1,l,r);else if(l > m) update(t << 1 | 1,l,r);else{update(t << 1,l,m);update(t << 1 | 1,m + 1,r);}tree[t].dp = max(tree[t << 1].dp,tree[t << 1 | 1].dp); } int query(int t,int l,int r){if(l <= tree[t].l && tree[t].r <= r) return tree[t].dp;Pushdown(t);int m = (tree[t].l + tree[t].r) >> 1;if(r <= m) return query(t << 1,l,r);else if(l > m) return query(t << 1 | 1,l,r);else return max(query(t << 1,l,m),query(t << 1 | 1,m + 1,r)); } int main(){Sca2(N,K);for(int i = 1; i <= N ; i ++) Sca(a[i]);Build(1,1,N);for(int i = 2; i <= K - 1; i ++){int p = query(1,1,i - 1,a[i]);// cout << p + 1 << " " << i - 1 << endl;if(p + 1 <= i - 1) update(1,p + 1,i - 1);}for(int i = K; i <= N ; i ++){if(K != 1){int p = query(1,i - K + 1,i - 1,a[i]);if(!p) p = i - K;// cout << p + 1 << " " << i - 1 << endl;if(p + 1 <= i - 1) update(1,p + 1,i - 1);}printf("%d ",query(1,i - K + 1,i));}return 0; }
G
转载于:https://www.cnblogs.com/Hugh-Locke/p/10712739.html
codeforces-1132 (div2)相关推荐
- codeforces#320(div2) D Or Game 贪心
codeforces#320(div2) D "Or" Game 贪心 D. "Or" Game time limit per test 2 seconds ...
- codeforces 628.div2
# Codeforces 628.div2 A. EhAb AnD gCd B. CopyCopyCopyCopyCopy C. Ehab and Path-etic MEXs D. Ehab the ...
- codeforces#324(div2) E. Anton and Ira 贪心
codeforces#324(div2) E. Anton and Ira 贪心 E. Anton and Ira time limit per test 1 second memory limit ...
- codeforces 712 div2 ABC
codeforces 712 div2 ABC A. Déjà Vu A palindrome is a string that reads the same backward as forward. ...
- codeforces round div2,3周赛补题计划(从开学到期末)
1. 本学期场次 从2020.09.19-2021.01.18,一共18周. 题号 场次 日期 备注 1475 Codeforces Round #697 (Div. 3) 1.25 1474 Cod ...
- Codeforces#371 Div2
这是一场非常需要总结的比赛,交了3题,最后终测的时候3题全部没过,一下掉到了绿名,2333 Problem A 题意:给定区间[l1,r1],[l2,r2],然后给定一个整数k,求区间当中相交的元素, ...
- 【Codeforces #130 Div2】Solutions
[208A Dubstep] http://codeforces.ru/problemset/problem/208/A 题目大意:一个句子被添加了若干"WUB",问原句. 将W ...
- 付忠庆的练习小笔记-Codeforces #277 Div2 C
原题链接 http://codeforces.com/contest/486/problem/C 这个C题显然更水一些 步数可以分为两种 上下一种 左右一种 总步数最小 = 上下最小+左右最小 先讨论 ...
- 付忠庆的练习小笔记-Codeforces #276 Div2 C
原题链接 http://codeforces.com/contest/485/problem/C 题意:给出一个区间 l~r 求这个区间内的数中转换成2进制含'1'最多的数,若有多组解,则输出最小的那 ...
- Codeforces 583 DIV2 Robot's Task 贪心
原题链接:http://codeforces.com/problemset/problem/583/B 题意: 就..要打开一个电脑,必须至少先打开其他若干电脑,每次转向有个花费,让你设计一个序列,使 ...
最新文章
- 计算机视觉迎新突破?谷歌AI模型打破现有CNNs精度
- 量子计算和量子模拟研究获进展
- Struts2笔记——result结果类型
- 西霞口船业公司疑遭外商合谋欺诈
- 我下载的mysql解压后没有安装_mysql 解压版安装配置方法教程
- Centos 6.5 64位双网卡绑定
- 20165310 Java实验五《网络编程与安全》
- 【CCF】201709-2公共钥匙盒
- 2022-01-31的新年flag
- 如何永久删除360SANDBOX?问题解决
- 地震数据爬取——Scrapy爬虫框架应用
- vue展示日历 考勤展示_Vue编写可显示周和月模式的日历 Vue自定义日历内容的显示...
- 高盛:云计算市场2021年将增至1160亿美元 四巨头成赢家
- Gson解析新浪微博数据
- PLC PID优化系列之非线性参数整定(FC函数)
- “三天打鱼,两天晒网”
- 杨立昆怒怼机器人索菲娅:AI硬加人类意识是揠苗助长
- 不同范数下的余弦定理_用向量证明余弦定理是否存在逻辑错误?
- data guard汇总(1)
- zlg72128数码管驱动管理显示芯片