結果
| 問題 | No.3407 Birds-of-Paradise' Christmas Live |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-12-12 22:58:12 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,193 bytes |
| 記録 | |
| コンパイル時間 | 2,999 ms |
| コンパイル使用メモリ | 278,972 KB |
| 実行使用メモリ | 7,852 KB |
| 最終ジャッジ日時 | 2025-12-13 23:30:13 |
| 合計ジャッジ時間 | 4,831 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 5 WA * 15 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
if(!(cin >> n)) return 0;
vector<int64> w(n);
for(int i=0;i<n;i++) cin >> w[i];
int m; cin >> m;
vector<int64> s(m);
for(int i=0;i<m;i++) cin >> s[i];
// マージして (bitW, bitS, len) のセグメント列を逐次生成して処理する
int iw = 0, is = 0;
int64 remW = (n>0 ? w[0] : 0);
int64 remS = (m>0 ? s[0] : 0);
auto bit_of_index = [](int idx)->int { return (idx % 2 == 0) ? 1 : 0; }; // 0-based index: 0 -> w1 -> ones
int64 answer = 0;
// 現在のブロックの DP。started=false の間はブロック未開始(直前に (0,0) があった状態)
bool started = false;
// dpK_score: 現在「末尾がK」であるときの最大スコア(ブロック内のみ含む)
// dpK_len: 末尾の連続忘れ K の長さ(スコアには既に含まれている)
int64 dpK_score = 0, dpK_len = 0;
int64 dpT_score = 0, dpT_len = 0;
auto flush_block = [&](){
if(!started) return;
answer += max(dpK_score, dpT_score);
started = false;
dpK_score = dpK_len = dpT_score = dpT_len = 0;
};
while(iw < n && is < m){
int bitW = bit_of_index(iw);
int bitS = bit_of_index(is);
int64 take = min(remW, remS);
remW -= take;
remS -= take;
if(remW == 0){
iw++;
if(iw < n) remW = w[iw];
}
if(remS == 0){
is++;
if(is < m) remS = s[is];
}
// このセグメント (bitW,bitS,take) を処理
if(bitW == 0 && bitS == 0){
// セパレータ:ブロック終了
flush_block();
continue;
}
// ブロック内セグメントとして扱う
if(!started){
// ブロック開始時の初期化
started = true;
if(bitW==1 && bitS==0){
// forced K
dpK_score = take * take;
dpK_len = take;
dpT_score = 0; dpT_len = 0; // impossible
// but keep dpT_score small so max works
} else if(bitW==0 && bitS==1){
dpT_score = take * take;
dpT_len = take;
dpK_score = 0; dpK_len = 0;
} else { // bitW==1 && bitS==1 -> flexible
// at block start we can choose either K or T for this flexible seg.
dpK_score = take * take; dpK_len = take;
dpT_score = take * take; dpT_len = take;
}
continue;
}
// 一般遷移
if(bitW==1 && bitS==0){
// forced K: T は impossible after this seg (cannot assign this seg to T)
// new K can be extending previous K or starting new from previous T
int64 cand_extendK = dpK_score + (2*dpK_len*take + take*take); // extend K run
int64 cand_fromT = dpT_score + (take*take); // switch from T -> start new K run
// It's possible dpK_score was 0 (if never had K before) but that's fine.
if(dpK_len==0 && dpK_score==0 && dpT_len==0 && dpT_score==0){
// shouldn't happen because started==true
}
if(cand_extendK >= cand_fromT){
dpK_score = cand_extendK;
dpK_len = dpK_len + take;
} else {
dpK_score = cand_fromT;
dpK_len = take;
}
// dpT becomes impossible for now
dpT_score = 0; dpT_len = 0;
} else if(bitW==0 && bitS==1){
// forced T
int64 cand_extendT = dpT_score + (2*dpT_len*take + take*take);
int64 cand_fromK = dpK_score + (take*take);
if(cand_extendT >= cand_fromK){
dpT_score = cand_extendT;
dpT_len = dpT_len + take;
} else {
dpT_score = cand_fromK;
dpT_len = take;
}
dpK_score = 0; dpK_len = 0;
} else {
// flexible (1,1): we may assign whole segment to K or to T.
// compute newK by either extending K or starting new from T; similarly for newT.
int64 newK_score1 = dpK_score + (2*dpK_len*take + take*take); // extend K
int64 newK_score2 = dpT_score + (take*take); // switch from T -> start K
int64 newK_score = max(newK_score1, newK_score2);
int64 newK_len = (newK_score1 >= newK_score2) ? (dpK_len + take) : take;
int64 newT_score1 = dpT_score + (2*dpT_len*take + take*take); // extend T
int64 newT_score2 = dpK_score + (take*take); // switch from K -> start T
int64 newT_score = max(newT_score1, newT_score2);
int64 newT_len = (newT_score1 >= newT_score2) ? (dpT_len + take) : take;
dpK_score = newK_score; dpK_len = newK_len;
dpT_score = newT_score; dpT_len = newT_len;
}
}
// 最後のブロックを確定
flush_block();
cout << answer << "\n";
return 0;
}