結果
| 問題 | No.3407 Birds-of-Paradise' Christmas Live |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-12-12 22:55:21 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,347 bytes |
| 記録 | |
| コンパイル時間 | 2,843 ms |
| コンパイル使用メモリ | 286,124 KB |
| 実行使用メモリ | 16,896 KB |
| 最終ジャッジ日時 | 2025-12-13 23:30:11 |
| 合計ジャッジ時間 | 4,753 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 5 WA * 15 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
const int64 NEG = LLONG_MIN / 4;
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);
vector<tuple<int,int,int64>> segs; // (bitW, bitS, len)
while(iw < n && is < m){
int bitW = (iw % 2 == 0) ? 1 : 0; // w1 is ones => iw=0 => 1
int bitS = (is % 2 == 0) ? 1 : 0; // same for s
int64 take = min(remW, remS);
segs.emplace_back(bitW, bitS, take);
remW -= take;
remS -= take;
if(remW == 0){
iw++;
if(iw < n) remW = w[iw];
}
if(remS == 0){
is++;
if(is < m) remS = s[is];
}
}
// DP をセグメント列上で実行
int64 answer = 0;
// dpK_total: 総スコア(現在の進行中ランも既にスコアに含めた形)
// dpK_len: 進行中の K ラン長(dpK_total に含まれているランの長さ)
int64 dpK_total = NEG, dpK_len = 0;
int64 dpT_total = NEG, dpT_len = 0;
auto flush_block = [&](){
if(dpK_total == NEG && dpT_total == NEG) return;
int64 best = max(dpK_total, dpT_total);
if(best != NEG) answer += best;
dpK_total = dpT_total = NEG;
dpK_len = dpT_len = 0;
};
for(auto &tp : segs){
int bitW, bitS; int64 len;
tie(bitW, bitS, len) = tp;
if(bitW==0 && bitS==0){
// separator: ブロック終了
flush_block();
continue;
}
// 保存しておく(遷移で上書きするので previous をキャプチャ)
int64 prevK_total = dpK_total, prevK_len = dpK_len;
int64 prevT_total = dpT_total, prevT_len = dpT_len;
if(bitW==1 && bitS==0){
// forced K
// new dpK = max( extend prevK, start new from prevT )
int64 cand1 = NEG, cand2 = NEG;
if(prevK_total != NEG){
// extend K
cand1 = prevK_total + (2*prevK_len*len + len*len);
}
if(prevT_total != NEG){
// switch from T to K, start new K run of length len
cand2 = prevT_total + (len*len);
}
if(prevK_total == NEG && prevT_total == NEG){
// beginning of block: start K here
cand2 = len*len;
}
dpK_total = max(cand1, cand2);
if(dpK_total == cand1) dpK_len = prevK_len + len;
else dpK_len = len;
// dpT impossible
dpT_total = NEG; dpT_len = 0;
} else if(bitW==0 && bitS==1){
// forced T
int64 cand1 = NEG, cand2 = NEG;
if(prevT_total != NEG){
cand1 = prevT_total + (2*prevT_len*len + len*len);
}
if(prevK_total != NEG){
cand2 = prevK_total + (len*len);
}
if(prevK_total == NEG && prevT_total == NEG){
cand2 = len*len;
}
dpT_total = max(cand1, cand2);
if(dpT_total == cand1) dpT_len = prevT_len + len;
else dpT_len = len;
dpK_total = NEG; dpK_len = 0;
} else {
// bitW==1 && bitS==1 : flexible -> can be assigned to K or T
// compute new dpK and dpT from previous both possibilities
int64 newK_total = NEG, newK_len = 0;
int64 newT_total = NEG, newT_len = 0;
// to K:
// extend prevK
if(prevK_total != NEG){
int64 val = prevK_total + (2*prevK_len*len + len*len);
if(val > newK_total){ newK_total = val; newK_len = prevK_len + len; }
}
// start K from prevT or from nothing
if(prevT_total != NEG){
int64 val = prevT_total + (len*len);
if(val > newK_total){ newK_total = val; newK_len = len; }
}
if(prevK_total == NEG && prevT_total == NEG){
// starting block
int64 val = len*len;
if(val > newK_total){ newK_total = val; newK_len = len; }
}
// to T:
if(prevT_total != NEG){
int64 val = prevT_total + (2*prevT_len*len + len*len);
if(val > newT_total){ newT_total = val; newT_len = prevT_len + len; }
}
if(prevK_total != NEG){
int64 val = prevK_total + (len*len);
if(val > newT_total){ newT_total = val; newT_len = len; }
}
if(prevK_total == NEG && prevT_total == NEG){
int64 val = len*len;
if(val > newT_total){ newT_total = val; newT_len = len; }
}
dpK_total = newK_total; dpK_len = newK_len;
dpT_total = newT_total; dpT_len = newT_len;
}
}
// 最後のブロックを足す
flush_block();
cout << answer << "\n";
return 0;
}