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;
}
浙公网安备 33010602011771号