TopCoder——SRM 520 DIV 2

国庆都放了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

 



你可能感兴趣的:(c,vector,String,测试,Class,div)