SRM527 Div1 Easy(275), Div2 Medium(550) P8XGraphBuilder
動的計画法。点数がiで木の数がjの森の最大コスコアを覚えておけば良い。それぞれの木に片方だけが繋がった辺(?)が1本ずつあるとして計算しておくと楽。点数が2以上ならば次数1の頂点が少なくとも1個あるはずなので、そこを最後にする。
#include <string> #include <vector> using namespace std; class P8XGraphBuilder{public: int solve( vector <int> scores ) { int N = (int)scores.size()+1; // S[i][j] // 点数i木の数jの森の、それぞれの木に辺を1つ加えた最大スコア vector<vector<int> > S( N, vector<int>(N) ); S[1][1] = scores[0]; for ( int i=2; i<=N-1; i++ ) { for ( int j=1; j<=i-1; j++ ) S[i][1] = max( S[i][1], S[i-1][j]+scores[j] ); for ( int j=1; j<=i; j++ ) for ( int k=1; k<=i-(j-1); k++ ) S[i][j] = max( S[i][j], S[k][1]+S[i-k][j-1] ); } return S[N-1][1]+scores[0]; }};