P1717 钓鱼 题解

P1717 钓鱼
多重背包-完全背包
其实因为在每一个地方都可以钓无限久的鱼,所以是完全背包
而又因为钓久了,鱼的数量就变成了负数了,所以又得当成多重背包做QAQ

跟多重背包不同的,这题每个池塘只能选一种钓鱼的时间长度,并不需要多重背包
只需要做01背包,并再加一层循环枚举钓鱼的时间

设状态 f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i个池塘,时限为 j j j,最多可以钓到多少鱼

转移是,考虑该池塘钓不钓鱼
不钓鱼: f [ i ] [ j ] = f [ i − 1 ] [ j − d i s [ i − 1 ] ] f[i][j]=f[i-1][j-dis[i-1]] f[i][j]=f[i1][jdis[i1]]
钓鱼:枚举钓鱼的时间 k k k ,并用变量 t m p tmp tmp记录鱼少了多少 f [ i ] [ j ] = m a x ( f [ i ] [ j ] , ( f [ i − 1 ] [ j − d i s [ i − 1 ] − k ] + a [ i ] ∗ ( k / 5 ) − t m p ) ) f[i][j]=max(f[i][j],(f[i-1][j-dis[i-1]-k]+a[i]*(k/5)-tmp)) f[i][j]=max(f[i][j],(f[i1][jdis[i1]k]+a[i](k/5)tmp))

#include
#include
using namespace std;
const int Maxn=40,Maxm=1020,inf=0x3f3f3f3f;
int a[Maxn],d[Maxn],dis[Maxn],f[Maxn][Maxm];
int n,m,ans;
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*w;
}
int main()
{
	//freopen("in.txt","r",stdin);
	n=read(),m=read()*60;
	for(int i=1;i<=n;++i)
	a[i]=read();
	for(int i=1;i<=n;++i)
	d[i]=read();
	for(int i=1;i<n;++i)
	dis[i]=read()*5;
	for(int i=1;i<=n;++i)
	for(int j=0;j<=m;++j)
	f[i][j]=-inf;
	f[1][0]=0;
	for(int i=1;i<=n;++i)
	{
		for(int j=m;j>=dis[i-1];--j)
		{
			f[i][j]=f[i-1][j-dis[i-1]];
			int tmp=0;
			for(int k=5;k<=j;k+=5)
			{
				if(j-dis[i-1]-k<0)break;
				f[i][j]=max(f[i][j],(f[i-1][j-dis[i-1]-k]+a[i]*(k/5)-tmp));
				tmp+=(k/5)*d[i];
			}
		}
	}
	for(int i=1;i<=n;++i)
	for(int j=0;j<=m;++j)
	ans=max(ans,f[i][j]);
	printf("%d\n",ans);
	return 0;
}

你可能感兴趣的:(题解)