TopCoder——SRM 518 DIV 2

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;
	}
	
	
};

Score 500.

枚举每一个字符,将位于当前字符之前的且 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;
	}
};

Score 1000.

假设到达第 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;
	}
};




你可能感兴趣的:(TopCoder——SRM 518 DIV 2)