結果
| 問題 |
No.1512 作文
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:03:16 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,064 bytes |
| コンパイル時間 | 724 ms |
| コンパイル使用メモリ | 81,268 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-05-14 13:04:50 |
| 合計ジャッジ時間 | 2,423 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 17 WA * 21 |
ソースコード
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // Needed for max
using namespace std;
// Use long long for lengths as the total length can potentially be large.
// The problem states the sum of |S_i| is at most 200000, which fits in a 32-bit signed integer.
// However, using long long is safer and handles larger potential sums if constraints were different.
typedef long long ll;
// Function to check if a string is "good".
// A string is good if its characters are in non-decreasing alphabetical order.
bool is_good(const string& s) {
// An empty string is considered good according to the problem statement examples.
// However, the constraint |S_i| >= 1 means we won't receive empty strings as input.
// If the string has 0 or 1 character, it's automatically good.
if (s.length() <= 1) {
return true;
}
// Check adjacent characters
for (size_t i = 0; i + 1 < s.length(); ++i) {
// If we find a pair where the current character is greater than the next one,
// the string is not sorted non-decreasingly, hence not good.
if (s[i] > s[i+1]) {
return false;
}
}
// If we iterated through all adjacent pairs and found no violations, the string is good.
return true;
}
int main() {
// Use faster I/O operations
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N; // Number of strings
cin >> N;
// L[c1][c2] will store the total length of all good input strings S_i
// such that S_i starts with character 'a'+c1 and ends with character 'a'+c2.
// We use a 2D vector of size 26x26, initialized to zeros.
vector<vector<ll>> L(26, vector<ll>(26, 0));
// Read N strings, check if each is good, and if so, aggregate its length into the L table.
for (int i = 0; i < N; ++i) {
string S;
cin >> S;
// The problem guarantees |S_i| >= 1, so strings are non-empty.
if (is_good(S)) {
// Get the 0-based indices for the first and last characters.
int first_char_idx = S.front() - 'a';
int last_char_idx = S.back() - 'a';
// Add the length of the good string to the corresponding cell in L.
L[first_char_idx][last_char_idx] += S.length();
}
}
// Dynamic Programming approach:
// dp[i] will store the maximum length of a good concatenated string
// that ends with the character 'a'+i.
vector<ll> dp(26, 0);
// This variable tracks the maximum value found in dp[k] for all k < i processed so far.
// It represents the maximum length of a good concatenated string ending *before* the current character 'a'+i.
ll max_dp_prefix = 0;
// Iterate through all possible ending characters 'a' through 'z' (indices 0 to 25).
for (int i = 0; i < 26; ++i) {
// Calculate term1: Represents the maximum length achieved by appending a block of strings
// that start at character 'a'+j (where j < i) and end at character 'a'+i.
// This block must follow a path ending at 'a'+j. The max length for such path is dp[j].
// We take the maximum over all possible previous characters 'a'+j.
ll term1 = 0;
for (int j = 0; j < i; ++j) {
// We can only transition from j to i if there exist good strings starting at 'a'+j and ending at 'a'+i.
// This is indicated by L[j][i] > 0.
if (L[j][i] > 0) {
// The length would be the max length ending at j (dp[j]) plus the total length of strings from j to i (L[j][i]).
term1 = max(term1, dp[j] + L[j][i]);
}
}
// Calculate term2: Represents the maximum length achieved by potentially appending a block of strings
// that both start and end at character 'a'+i (total length L[i][i]).
// Such a block can follow any path that ends at a character 'a'+k where k < i.
// The maximum length among such preceding paths is captured by max_dp_prefix.
ll term2 = max_dp_prefix + L[i][i];
// The maximum length ending at character 'a'+i (dp[i]) is the maximum of the two possibilities calculated above.
// Note that if L[i][i] is 0, term2 effectively represents just continuing a path from before 'i' without adding strings starting and ending at 'i'.
// If L[j][i] is 0 for all j < i, term1 will be 0.
// dp[i] calculation correctly covers cases where paths start fresh with strings corresponding to L[j][i] or L[i][i].
dp[i] = max(term1, term2);
// Update max_dp_prefix to include the newly computed dp[i].
// This ensures max_dp_prefix stores max(dp[k] for k <= i) for the next iteration.
max_dp_prefix = max(max_dp_prefix, dp[i]);
}
// After iterating through all characters, max_dp_prefix holds the maximum value across all dp[i],
// which corresponds to the maximum possible length of a good concatenated string.
cout << max_dp_prefix << endl;
return 0;
}
qwewe