免费馅饼

问题

dp可以解,在每个i 点位置,都有三种选择,1)原地“待饼” 2)左移 3)右移。这里位置可能会重复,所以我们还的加一个状态变量,就是时间,我们用dp[i,j]来表示在第i 秒,在第 j 的位置所得到的最多的馅饼。

则状态转移方程为 : dp [ i, j ] = max{ dp[ i + 1] [ j ] , dp [ i + 1] [ j - 1] , dp[i + 1] [ j + 1] } ,右边是 i  + 1 ,是因为倒计时。

这还没算完,那我们 最终的状态什么呢,最终会在时间为0 即i = 0,但是 j 是多少呢? 这鬼知道啊。我们再把问题倒过来看,反正是得到最多的馅饼,那我们就把这个过程中所站的点构成的序列倒过来,前锋断后,后卫变前锋,对,将初始点 j = 5,作为终止的点,那么我们的最终结果就是dp[ 0 ] [ 5 ]了。

#define  _CODE_HDOJ_A1176_
#ifdef _CODE_HDOJ_A1176_
/************************************************************************
f[i][j]: at time i, position j, the max he can get.
trans function: at f[i][j], he has three choices, 1)stand there and go nowhere.
2)go to left. 3)go to right.

f[i][j] = max{f[i+1][j], f[i+1][j+1], f[i+1][j-1]}
/************************************************************************/
#include <stdio.h>
#include <string.h>

const int N = 100002;
const int P = 11;

int f[N][P+2];

inline int max3(int a, int b, int c)
{
	if(a < b) a = b;
	if(a < c) a = c;
	return a;
}

int main()
{
	int n;
	freopen("a1176.txt","r",stdin);
	while (scanf("%d", &n), n)
	{
		int maxtime = -1;
		memset(f, 0, sizeof(f));
		for (int i = 0; i < n; ++i)
		{
			int p, t;
			scanf("%d%d",&p, &t);
			f[t][p+1]++; //0-10 to 1-11
			if(t > maxtime)
				maxtime = t;
		}
		for (int time = maxtime - 1; time >= 0; --time)
		{
			for (int pt = 1; pt <= 11; ++pt)
			{
				f[time][pt] += max3(f[time+1][pt], f[time+1][pt+1],f[time+1][pt-1]);
			}	
		}
		printf("%d\n",f[0][6]);
	}
	return 0;
}
#endif

这里将下标从1开始,没从0开始,所以是f[0][6].

免费馅饼

上一篇:CareerCup Find the biggest interval that has all its members in list in O(n)


下一篇:Java垃圾回收器总结