SRM311 div2 medium
変則的な動的計画法の問題.問題の趣向から、iを逆順に回して最大値を簡単に取得できるようにしている.
また、j++とすることで、暗に数字を複数回使ってよいことを表している.
もし、 for(int j = n; j >= matches[i]; j--) { ... } としてみると、数字は一回しか使われないことが分かる.
/* これはまずい.stringの長さが20とかだったらintがoverflowをおこしてしまう。 結果が代わってくるので、stringのまま処理しなければならない. string maxToInt(string a, string b) { if(a == "" || b == "") { return (a == "") ? b : a; } int numa; int numb; sscanf(a.c_str(), "%d", &numa); sscanf(b.c_str(), "%d", &numb); return (numa > numb) ? a : b; } */ //これなら、stringがどんな長さでも数字順に並ぶ. string maxToInt(string a, string b) { string ans = ""; int lena = a.length(); int lenb = b.length(); if(lena > lenb) ans = a; else if(lena < lenb) ans = b; else ans = (a > b) ? a : b; return ans; } class MatchNumbersEasy { public: string maxNumber(vector <int> matches, int n) { int sz = matches.size(); string dp[51][51]; //dp[sz+1][n+1] fill(dp[0], dp[0]+51*51, ""); for(int i = sz-1; i >= 0; i--) { for(int j = matches[i]; j <= n; j++) { char ch = i + '0'; dp[i][j] = max(dp[i][j-matches[i] ] + ch, dp[i+1][j]); } } return dp[0][n]; }