SRM 499 Div2 Hard PalindromeGame
問題
n枚のカードがあり、表には単語、裏には数字が書かれている。
それぞれのカードに書かれている単語の文字数は全て等しい。
これらのカードのうちいくつかを並べて回文を作るとき、
裏にかかれている数字の和を最大にしたい。そのような和の最大値を求めよ。
回文が作れないときは0を返せ。
制約条件
n≦50
回文の問題苦手だよなーと思ったら正解者かなり多い問題なのにやはりハマったorz
方針
単語の文字数は全て同じ。
したがって、回文の両端に相当するカードから2枚ずつ順々に決定していけばいい。
あるカードに対応するカードが複数枚ある可能性がある(abc,abc,cbaみたいに)ので、
点数の高いカードからGreedyに使うようにする。
2枚ずつカードを選び終わったら、中央に1枚カードが挟まる(1枚のカードがそれだけで回文になっている)可能性を考える。
これも複数候補がある場合、もっとも数字の大きいカードを使えばよい。
ソースコード
class PalindromeGame { public: int getMaximum(vector <string> front, vector <int> back) { int n=front.size(), ans=0; vector<pair<int,string> > v; rep(i,n)v.pb(mp(-back[i], front[i])); sort(all(v)); rep(i,n)front[i]=v[i].second, back[i]=-v[i].first; rep(i,n)if(front[i]!=""){ reverse(all(front[i])); rep(j,i)if(front[i]==front[j]){ ans+=back[i]+back[j]; front[i]=front[j]=""; break; } reverse(all(front[i])); } rep(i,n)if(front[i]!=""){ string r=front[i]; reverse(all(r)); if(r==front[i]){ ans+=back[i]; break; } } return ans; } };