国庆都放了9天的假,我却还是那么忙!研究课题的感觉真不爽,哪还能熬夜做 TCO!下午(2011.10.05)终于忙里偷闲,回味了昨晚的一场TC~
Score 250.
这题很简单了,统计值大于 ratings[0] 的个数,再除以 K 便是答案了~
#include<cstdio> #include<vector> using namespace std; class SRMRoomAssignmentPhase { public: int countCompetitors(vector <int> ratings, int K) { int ret = 0, cmp = ratings[0]; for(int i = 0; i < (int)ratings.size(); ++i) if( ratings[i] > cmp ) ++ret; return ret / K; } };
Score 500.
这题我们可以枚举分配给三道题的幸运值 La, Lb, Lc 得到最优值,当然了,肯定需要满足 La + Lb + Lc <= Luck,Luck 的值最大才 100,可以搞定,不多说了~
#include<cstdio> #include<cstring> #include<vector> #include<iostream> #include<algorithm> using namespace std; class SRMCodingPhase { public: int countScore(vector <int> points, vector <int> skills, int luck) { int i, j, k, ans = 0, a, b, c, ta, tb, tc; for(i = 0; (i < skills[0]) && (i <= luck); ++i) { for(j = 0; (j < skills[1]) && (i + j <= luck); ++j) { for(k = 0; (k < skills[2]) && (i + j + k <= luck); ++k ) { ta = skills[0] - i; tb = skills[1] - j; tc = skills[2] - k; a = points[0] - 2 * ta; b = points[1] - 4 * tb; c = points[2] - 8 * tc; if( ta + tb + tc <= 75 ) ans = max(ans, a + b + c); if( ta + tb <= 75 ) ans = max(ans, a + b); if( ta + tc <= 75 ) ans = max(ans, a + c); if( tb + tc <= 75 ) ans = max(ans, b + c); if( ta <= 75 ) ans = max(ans, a); if( tb <= 75 ) ans = max(ans, b); if( tc <= 75 ) ans = max(ans, c); } } } return ans; } };
Score 1000.
这题很有意思,动态规划。
不妨定义 DP[ n ][ pas ][ fal ][ cha ] 表示第 n 个人通过了 pas 道题,系统测试时不幸挂了 fal 题,而且还被人挑了 cha 道题;
容易知道,pas、fal 、cha 的和是定值,即
pas + fal + cha = const = N( ‘Y’ )
上式中,N( ‘Y’ )表示第 n 个人的做题情况中 ‘Y’ 的个数。
当前状态取决于第 n-1 个人的状态,容易知道,对于第 n-1 个人也有 pas、fal 和 cha 三个分量,不妨改记为 ipas、ifal 和 icha。
那么有
如果满足条件
( ipas > pas ) || ( ipas == pas && icha < cha ) || ( ipas == pas && icha == cha )
那么
DP[ n ][ pas ][ fal ][ cha ] += DP[ n - 1 ][ ipas ][ ifal ][ icha ]
是不是这样呢?
注意,条件是对的,但是结论有错,不能简单的直接加上 DP[ n - 1 ][ ipas ][ ifal ][ icha ],
因为对于第 n 个人的一个状态,是有组合性质的,即如果第 n 个人 有 3 道题是 'Y',
其中,有1道题通过,有1道题挂了,还有1道题被挑了,而3道题是不同的,所以这里还需要考察排列组合。
所以,更改上面的描述就是
如果满足条件
( ipas > pas ) || ( ipas == pas && icha < cha ) || ( ipas == pas && icha == cha )
那么
DP[ n ][ pas ][ fal ][ cha ] += C[ N( 'Y' ) ][ pas ] * C[ N( 'Y' ) - pas ][ fal ] * C[ N( 'Y' ) - pas - fal ][ cha ] * DP[ n - 1 ][ ipas ][ ifal ][ icha ]
好了,思路到这里,搞定这道题就不再是难事了~
#include<cstdio> #include<vector> #include<string> #include<algorithm> using namespace std; const long long MOD = 1000000007LL; long long Comb[4][4] = { {1LL, 0LL, 0LL, 0LL}, {1LL, 1LL, 0LL, 0LL}, {1LL, 2LL, 1LL, 0LL}, {1LL, 3LL, 3LL, 1LL}}; class SRMSystemTestPhase { public: long long dp[51][4][4][4]; int Y[51], nY; int countWays(vector <string> description) { memset(dp, 0, sizeof(dp)); nY = (int)description.size(); memset(Y, 0, sizeof(Y)); for(int i = 0, j; i < nY; ++i) for(j = 0; j < 3; ++j) if( description[i][j] == 'Y' ) ++Y[i]; int n, pas, fal, cha; for(pas = 0; pas <= Y[0]; ++pas) { for(fal = 0; fal + pas <= Y[0]; ++fal) { cha = Y[0] - fal - pas; dp[0][pas][fal][cha] = Comb[ Y[0] ][ pas ] * Comb[ Y[0] - pas ][ fal ]; } } int ipas, ifal, icha; for(n = 1; n < nY; ++n) { //printf("Y[%d] = %d...\n", n, Y[n]); for(pas = 0; pas <= Y[n]; ++pas) { for(fal = 0; fal + pas <= Y[n]; ++fal) { cha = Y[n] - fal - pas; for(ipas = 0; ipas <= Y[n - 1]; ++ipas) { for(ifal = 0; ifal + ipas <= Y[n - 1]; ++ifal) { icha = Y[n - 1] - ifal - ipas; //if( n == 1 ) printf("pas = %d, fal = %d, cha = %d, ipas = %d, ifal = %d, icha = %d\n", pas, fal, cha, ipas, ifal, icha); if( (ipas > pas) || (ipas == pas && icha < cha) || (ipas == pas && icha == cha) ) { dp[n][pas][fal][cha] += (Comb[ Y[n] ][ pas ] * (Comb[ Y[n] - pas ][ fal ] * dp[n - 1][ipas][ifal][icha] % MOD) % MOD); dp[n][pas][fal][cha] %= MOD; //if( n == 1 ) printf("dp[%d][%d][%d][%d] = %lld\n", n, pas, fal, cha, dp[n][pas][fal][cha]); } } } } } } long long ans = 0; int Last = nY - 1; for(pas = 0; pas <= Y[Last]; ++pas) { for(fal = 0; fal + pas <= Y[Last]; ++fal) { cha = Y[Last] - fal - pas; ans += dp[Last][pas][fal][cha]; ans %= MOD; } } return (int)(ans & 0x7fffffff); } };
hzwu @ 2011.10.05 @ SWJTU