Codeforces 919 行+列前缀和 树上记忆化搜索(树形DP)
A
B
C
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; get min const double eps = 1.0e-8; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; //const int maxn = 3e5 + 10; const int maxm = 300; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //priority_queue<int, vector<int>, less<int>> que; //next_permutation ll mod = 3e7; int pop = 0; char f[2005][2005]; int dp1[2005][2005]; int dp2[2005][2005]; string a; int main() { int n, m, k; cin >> n >> m >> k; int anser = 0; char ch; for (int i = 1; i <= n; i++) { scanf("%s", f[i] + 1); } if (k == 1) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { ch = f[i][j]; if (ch == '.') { anser++; } } } cout << anser << endl; return 0; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { ch = f[i][j]; if (ch == '*') { dp1[i][j] = dp2[i][j] = 0; } else { dp1[i][j] = dp1[i - 1][j] + 1; dp2[i][j] = dp2[i][j - 1] + 1; if (dp1[i][j] >= k) { anser++; } if (dp2[i][j] >= k) { anser++; } } } } cout << anser << endl; return 0; }
D
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; get min const double eps = 1.0e-8; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; //const int maxn = 3e5 + 10; const int maxm = 300; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //priority_queue<int, vector<int>, less<int>> que; //next_permutation ll mod = 3e7; int pop = 0; vector<int> tree[300005]; int visit[300005]; int vis[300005]; int dp[300005][30]; int ans[300005]; int gone[300005]; int num[300005]; int aim[30]; string a; int anser = 0; int flag = 0; void dfs(int x) { gone[x] = 1; int len = tree[x].size(); for (int i = 0; i < len; i++) { int to = tree[x][i]; if (gone[to] == 1) { cout << -1 << endl; exit(0); } else if (gone[to] == 2) { for (int j = 0; j < 26; j++) { int add = num[x] == j; dp[x][j] = max(dp[x][j], dp[to][j] + add); } } else { dfs(to); for (int j = 0; j < 26; j++) { int add = num[x] == j; dp[x][j] = max(dp[x][j], dp[to][j] + add); } } } gone[x] = 2; } int main() { int n, m; int from, to; cin >> n >> m; cin >> a; for (int i = 0; i < a.size(); i++) { num[i + 1] = a[i] - 'a'; dp[i + 1][num[i + 1]] = 1; } for (int i = 1; i <= m; i++) { scanf("%d %d", &from, &to); tree[from].pb(to); } for (int i = 1; i <= n; i++) { if (!gone[i]) { dfs(i); } } for (int i = 1; i <= n; i++) { for (int j = 0; j <= 25; j++) { ans[i] = max(ans[i], dp[i][j]); } anser = max(anser, ans[i]); } cout << anser << endl; return 0; }