EOJ:Roller Coaster

——贝茜滑冰,一共有n段。每段或者睁眼或者闭眼。如果一段睁着眼则好感度和晕眩度增加,若闭眼则好感度不变,晕眩度下降。求在不超过晕眩度上限的情况下获得的做大好感度。

——背包问题,注意维度表示的量

——http://202.120.106.94/onlinejudge/problemshow.php?pro_id=589

————————————————————————————————————————————————

首先,大家都能想到的方程:DP[I][J]表示第I个物品晕眩度为J时能获得的最大好感度。

但是由于原题中I<=1000而J<=300000,所以这个转移铁定超时。

————————————————————————————————————————

注意到好感度最多为20*1000=20000

因此转换维度

DP[I][J]表示第I个物品好感度为J是的最小晕眩度。

注意当DP[I][J]>limit的时候,不能用于进行转移

#include<stdio.h>
#define N 1001
#define oo 0x7ffffff
int dp[2][N*20],f[N],d[N];
int n,k,l,i,j,r,nr,up_bound,maxm;
int min(int a,int b)
{
	return a<b?a:b;
}
int main()
{
	while (1)
	{
		scanf("%d%d%d",&n,&k,&l);
		if (n==0)
			break;
		for (i=0;i<=1;i++)
			for (j=0;j<=n*20;j++)
				dp[i][j]=oo;
		for (i=1;i<=n;i++)
			scanf("%d%d",&f[i],&d[i]);
		dp[0][0]=0;
		r=1;
		nr=0;
		up_bound=0;
		maxm=0;
		for (i=0;i<n;i++)
		{
			r=(r+1)%2;
			nr=(nr+1)%2;
			for (j=0;j<=up_bound;j++)
				if (dp[r][j]<=l)
				{
					dp[nr][j+f[i+1]]=min(dp[nr][j+f[i+1]],dp[r][j]+d[i+1]);
					dp[nr][j]=min(dp[nr][j],dp[r][j]-k);
					if (dp[nr][j]<0)
						dp[nr][j]=0;
					if (dp[nr][j+f[i+1]]<=l&&j+f[i+1]>maxm)
						maxm=j+f[i+1];
				}
			up_bound=maxm;
		}
		printf("%d\n",maxm);
	}
	return 0;
}

  

posted on 2011-08-13 21:29  风也轻云也淡  阅读(158)  评论(0编辑  收藏  举报