USACO 1.1 Broken Necklace (DP动态规划)

<pre name="code" class="cpp">#include <stdio.h>
#define DEBUG 0
#define TESTCASES 8

#define LEN_NECKLACE 350
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )

int numOfBeads;
int numOfDoubleBeads;
char necklace[LEN_NECKLACE * 2 + 1];


// beadsCollectedForward[bead][0]表示当断点为bead-1和bead之间时, 从bead开始往前(右)连续收集到红色珠子的数量
// beadsCollectedForward[bead][1]表示当断点为bead-1和bead之间时, 从bead开始往前(右)连续收集到蓝色珠子的数量
int beadsCollectedForward[LEN_NECKLACE * 2 + 1][2];
// beadsCollectedBackward[bead][0]表示当断点为bead和bead+1之间时, 从bead开始往后(左)连续收集到红色珠子的数量
// beadsCollectedBackward[bead][1]表示当断点为bead和bead+1之间时, 从bead开始往后(左)连续收集到蓝色珠子的数量
int beadsCollectedBackward[LEN_NECKLACE * 2 + 1][2];

void strCpy(char *to, char *from){
	while (*to = *from){
		if (*from == '\0')
			break;
		to++;
		from++;
	}
	*to = '\0';
}

void strCat(char *before, char *after){
	while (*before != '\0')
		before++;
	while (*after != '\0'){
		*before = *after;
		before++;
		after++;
	}
	*before = '\0';
}

void initialBeadsCollected(int beadsCollected[][2], int bead){
	switch (necklace[bead]){
		case 'w':
			beadsCollected[bead][0] =  1;
			beadsCollected[bead][1] =  1;
			break;
		case 'r':
			beadsCollected[bead][0] = 1;
			beadsCollected[bead][1] = 0;
			break;
		case 'b':
			beadsCollected[bead][0] = 0;
			beadsCollected[bead][1] = 1;
			break;
	}
}

void collect(int beadsCollected[][2], int bead, int direction){
	switch (necklace[bead]){
		case 'w':
			beadsCollected[bead][0] = beadsCollected[bead - direction][0] + 1;
			beadsCollected[bead][1] = beadsCollected[bead - direction][1] + 1;
			break;
		case 'r':
			beadsCollected[bead][0] = beadsCollected[bead - direction][0] + 1;
			beadsCollected[bead][1] = 0;
			break;
		case 'b':
			beadsCollected[bead][0] = 0;
			beadsCollected[bead][1] = beadsCollected[bead - direction][1] + 1;
			break;
	}
}

int main(){
#if DEBUG
	int testCase;
	for (testCase = 1; testCase <= TESTCASES; testCase++){
		char inputFileName[20] = "necklace.inX";
		inputFileName[11] = '1' +  (testCase - 1);
		freopen(inputFileName, "r", stdin);
		printf("#%d\n", testCase);
#endif
	
	scanf("%d %s", &numOfBeads, necklace);

	//两条链子相连当成环处理
	numOfDoubleBeads = numOfBeads * 2;
	char temp[LEN_NECKLACE * 2 + 1];
	strCpy(temp, necklace);
	strCat(necklace, temp);

	int bead = 0;
	initialBeadsCollected(beadsCollectedBackward, bead);
	for (bead++; bead < numOfDoubleBeads; bead++)
		collect(beadsCollectedBackward, bead, 1);
	bead = numOfDoubleBeads - 1;
	initialBeadsCollected(beadsCollectedForward, bead);
	for (bead--; bead >= 0; bead--)
		collect(beadsCollectedForward, bead, -1);

	int maxBeadsCollected = 0;
	int lastBead = numOfDoubleBeads - 1;
	//注意边界,断点在bead和bead+1之间,从bead开始往后(左)收集,从bead+1开始往前(右)收集
	for (bead = 0; bead < lastBead; bead++){
		int beadsCollected = MAX(beadsCollectedBackward[bead][0], beadsCollectedBackward[bead ][1]) +
						   MAX(beadsCollectedForward[bead + 1][0], beadsCollectedForward[bead + 1][1]);
		if (beadsCollected > maxBeadsCollected)
			maxBeadsCollected = beadsCollected;					
	}
		
	printf("%d\n", maxBeadsCollected > numOfBeads ? numOfBeads : maxBeadsCollected);

#if DEBUG
	}
#endif
	return 0;
}


 
 
 
 
 
 
 
 

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值