A.简单dp。
#include<bits/stdc++.h> using namespace std; int n,a[105],dp[105][2] = {0}; int main() { ios::sync_with_stdio(0); cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; int ans = 0; for(int i = 1;i <= n;i++) { if(a[i] == 0) { dp[i][0] = dp[i-1][0]+1; dp[i][1] = dp[i-1][1]; } else { dp[i][0] = dp[i-1][0]; dp[i][1] = max(dp[i-1][0],dp[i-1][1])+1; } } cout << max(dp[n][0],dp[n][1]) << endl; return 0; }
B.枚举凑满了几个task。
#include<bits/stdc++.h> using namespace std; int n,m,k,a[50]; int main() { ios::sync_with_stdio(0); cin >> n >> k >> m; int sum = 0; for(int i = 1;i <= k;i++) { cin >> a[i]; sum += a[i]; } sort(a+1,a+1+k); int ans = 0; for(int i = 0;i <= n;i++) { int cnt = n-i,left = m-sum*i,now = (k+1)*i; if(left < 0) break; for(int j = 1;j <= k;j++) { if(left < a[j]*cnt) { now += min(cnt,left/a[j]); break; } now += cnt; left -= a[j]*cnt; } ans = max(ans,now); } cout << ans << endl; return 0; }
C.预处理左右两个数的最大值,枚举中间那个点。
#include<bits/stdc++.h> using namespace std; int n,l[5005],r[5005]; long long a[5005],sum[5005] = {0},lm[5005],rm[5005]; long long f(int l,int r) { long long t1 = r == 0?0:sum[r-1]; long long t2 = l == 0?0:sum[l-1]; return t1-t2; } int main() { ios::sync_with_stdio(0); cin >> n; for(int i = 0;i < n;i++) { cin >> a[i]; sum[i] = sum[i-1]+a[i]; } for(int i = 0;i <= n;i++) { int t; long long maxx = -1e18; for(int j = 0;j <= i;j++) { if(f(0,j)-f(j,i) > maxx) { maxx = f(0,j)-f(j,i); t = j; } } l[i] = t; lm[i] = maxx; maxx = -1e18; for(int j = i;j <= n;j++) { if(f(i,j)-f(j,n) > maxx) { maxx = f(i,j)-f(j,n); t = j; } } r[i] = t; rm[i] = maxx; } long long maxx = -1e18; int ans1,ans2,ans3; for(int i = 0;i <= n;i++) { if(lm[i]+rm[i] > maxx) { maxx = lm[i]+rm[i]; ans1 = l[i]; ans2 = i; ans3 = r[i]; } } cout << ans1 << " " << ans2 << " " << ans3 << endl; return 0; }
D.二分答案,二维前缀和判断。
#include<bits/stdc++.h> using namespace std; int n,m,k,q,mp[505][505]; struct xx { int x,y,t; friend bool operator<(xx a,xx b) { return a.t < b.t; } }a[250005]; bool ok(int t) { memset(mp,0,sizeof(mp)); for(int i = 1;i <= q && a[i].t <= t;i++) mp[a[i].x][a[i].y] = 1; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) mp[i][j] += mp[i][j-1]+mp[i-1][j]-mp[i-1][j-1]; } for(int i = 1;i <= n-k+1;i++) { for(int j = 1;j <= m-k+1;j++) { int endx = i+k-1,endy = j+k-1; if(mp[endx][endy]-mp[i-1][endy]-mp[endx][j-1]+mp[i-1][j-1] == k*k) return 1; } } return 0; } int main() { ios::sync_with_stdio(0); cin >> n >> m >> k >> q; for(int i = 1;i <= q;i++) cin >> a[i].x >> a[i].y >> a[i].t; sort(a+1,a+1+q); int l = 0,r = 1e9+5; while(l < r) { int mid = (l+r)/2; if(ok(mid)) r = mid; else l = mid+1; } if(l == 1e9+5) cout << -1 << endl; else cout << l << endl; return 0; }
E.dfs从下到上处理每个点,注意超long long,负值太大直接NO。
#include<bits/stdc++.h> using namespace std; int n,ok = 1; long long a[100005],b[100005]; struct xx { int to,k; xx(int a,int b):to(a),k(b){}; }; vector<xx> v[100005]; void dfs(int now) { for(int i = 0;i < v[now].size();i++) { int t = v[now][i].to,k = v[now][i].k; dfs(t); if(a[t] < 0) { if(1.0*a[t]*k+a[now] < -1e17) ok = 0; a[now] += a[t]*k; } else a[now] += a[t]; } } int main() { ios::sync_with_stdio(0); cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= n;i++) cin >> b[i],a[i] -= b[i]; for(int i = 2;i <= n;i++) { int x,y; cin >> x >> y; v[x].push_back(xx(i,y)); } dfs(1); if(ok && a[1] >= 0) cout << "YES" << endl; else cout << "NO" << endl; return 0; }
F.记录每一个值的上一个位置,就容易计算每个点加入时增加的总价值。
#include<bits/stdc++.h> using namespace std; int n,a[1000005],la[1000005] = {0}; int main() { ios::sync_with_stdio(0); cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; long long ans = 0; for(int i = 1;i <= n;i++) { long long t1 = i-la[a[i]],t2 = n-i+1; ans += t1*t2; la[a[i]] = i; } ans *= 2; ans -= n; cout << fixed << setprecision(10) << 1.0*ans/n/n << endl; return 0; }