Score 250.
枚举最长的子串使得 S[ i --> (Ls - 1) ] = S[ 0 --> (Ls - i - 1) ] 即可。
class TwiceString { public: string getShortest(string s) { int L = (int)s.length(); string s1 = s, s2 = s; int same = 1; for(int i = 1; i < L; ++i) if( s[i] == s[i-1] ) ++same; if( same == L ) { s += s[0]; return s; } for(int pos = 1; pos < L; ++pos) { bool ok = 1; for(int i = pos; i < L; ++i) if( s1[i] != s2[i - pos] ) { ok = 0; break; } if( ok ) { for(int i = L - pos; i < L; ++i) s1 += s2[i]; return s1; } } return s1 + s2; } };
枚举每一个字符,将位于当前字符之前的且 ASCII 值小于当前字符舍去。
class LargestSubsequence { public: bool vst[60]; string getLargest(string s) { int L = (int)s.length(); memset(vst, 0, sizeof(vst)); for(int i = 1; i < L; ++i) for(int j = 0; j < i; ++j) if( !vst[i] && s[i] > s[j] ) vst[j] = 1; string ans; for(int i = 0; i < L; ++i) if( !vst[i] ) ans += s[i]; return ans; } };
假设到达第 k 步时,向上硬币数期望为 E(k),那么有
E( k ) = E( k-1 ) + F( N, A[ k ], E( k - 1 ) )
其中 F( N, A[ k ], E( k - 1 ) ) 表示期望增量函数
我们知道,在没有进行当前翻转的时候,已经有 E( k - 1 ) 个硬币朝上,N - E( k - 1 ) 个硬币朝下,现在需要翻转 A[ k ] 个硬币
容易知道翻转的 A[ k ] 个硬币来源有 3 类,其一,全部来自朝下硬币;其二,全部来自朝上硬币;最后,部分来自朝上硬币,部分来自朝下硬币
进一步考虑,第 3 类情况可以转化为第 1 类或者第 2 类,因为,假设第 3 类情况 有 x 个来自朝上, y 个来自朝下 ( x + y = A[ k ] )
不妨令 x < y,所以实际上只有 (y - x) 个来自朝下的硬币最终得到不同的翻转,情况同 第 1 类情况。同理知 x > y 和 x = y 的情况。
这样,我们能得到
F( * ) = F( *, y ) - F( *, x )
其中,F( *, y ) 表示从向下的硬币翻转 A[ k ] 的数学期望,所以
F( *, y ) = P( *, y) * N( *, y )
容易知道,P( *, y ) = ( N - E( k - 1 ) ) / N,N( *, y ) = A[ k ]
同理有
F( *, x ) = P( *, x ) * N( *, x )
P( *, x ) = E( k - 1 ) / N,N( *, x ) = A[ k ]
这样,我们有
F( * ) = F( *, y ) - F( *, x ) = ( N - 2 * E( k - 1 ) ) / N * A[ k ]
class CoinReversing { public: double expectedHeads(int N, vector <int> a) { int L = (int)a.size(); double ans = N; for(int i = 0; i < L; ++i) ans += (N - 2.0 * ans) * a[i] / N; return ans; } };