SRM532 Div1 Easy - DengklekMakingChains
コーナーケース系のやつ
問題
チェーンがn個あり、i番目はs[i]である
各チェーンは '0' 〜 '9' の数字と '.' のみからなる3文字の文字列である
このチェーンを任意の順番で1列に繋ぎ、数字のみからなる連続な部分列を取り出し、数字の和をスコアとする
スコアの最大値を求めよ
1 <= n <= 50
解法
3文字とも数字のチェーンは全部ひとまとめにしてしまっていい
これらの集合をcenとし、数字じゃない文字を含むチェーンの集合をtとする
cenの右端と左端それぞれに繋げるのはそれぞれたかだか1個のチェーンだけ
これをtから重複しないように選んで全探索する
やることはこれだけ
気をつけた点は
・ 重複禁止の2重ループだと集合tがサイズ1のとき困る
=> "..." というダミーを入れればcenの左/右の片方だけに付ける場合も試せる🤠
・ cenを含む部分列のスコアより、tに含まれるあるチェーン単体の部分列のスコアの方が大きくなり得る
=> 各チェーン単体のスコアでも答えを更新しておけば良い🤠
実装があんまスマートじゃないかな?
class DengklekMakingChains { public: int maxBeauty(vector<string> s) { vector<string> t; int res = 0, cen = 0; each(i,s) { if (isdigit(i[0]) && isdigit(i[1]) && isdigit(i[2])) cen += i[0]-'0' + i[1]-'0' + i[2]-'0'; else { t.push_back(i); if (isdigit(i[1])) { if (isdigit(i[0])) chmax(res, i[1]-'0' + i[0]-'0'); else if (isdigit(i[2])) chmax(res, i[1]-'0' + i[2]-'0'); else chmax(res, i[1]-'0'); } else { if (isdigit(i[0])) chmax(res, i[0]-'0'); else if (isdigit(i[2])) chmax(res, i[2]-'0'); } } } chmax(res, cen); t.push_back("..."); int m = t.size(); rep(l,m) rep(r,m) if (l!=r) { int sum = cen; if (isdigit(t[l][2])) { sum += t[l][2]-'0'; if (isdigit(t[l][1])) sum += t[l][1]-'0'; } if (isdigit(t[r][0])) { sum += t[r][0]-'0'; if (isdigit(t[r][1])) sum += t[r][1]-'0'; } chmax(res, sum); } return res; } };