记录编号 272311 评测结果 AAAAAAAAAA
题目名称 [HNOI 1999] 快餐问题 最终得分 100
用户昵称 Gravatar洛克索耶夫 是否通过 通过
代码语言 C++ 运行时间 0.058 s
提交时间 2016-06-16 20:00:38 内存使用 1.00 MiB
显示代码纯文本
#include<bits/stdc++.h>

//一条生产线时间t,产j汉堡k薯条,则生产(t*i-j*p1-k*p2)/p3饮料 
int f[15][110][110]={0};
//f[i][j][k]前i生产线生产j汉堡和k薯条,则最多生产的饮料数 
//另外要有第i生产线生产j汉堡k薯条,则生产饮料数 
int t[15]={0};
int a,b,c,p1,p2,p3,n,tot,ans=0,tc=0,maxn=0,maxa=0,maxb=0,maxc=0,pack=0;

inline int GetMax(const int& a,const int& b)
{
	return a>b?a:b;
}

inline int GetMin(int a, int b)
{
	return a<b?a:b;
}

bool Init()
{
	scanf("%d%d%d%d%d%d%d",&a,&b,&c,&p1,&p2,&p3,&n);
	tot=p1*a+p2*b+p3*c;
	int pack=0,tmp=0,sum=0;//最多生产pack个套餐 
	maxn=GetMin(100/a,GetMin(100/b,100/c));//最最最最多生产的套餐数 
	for (int i=1;i<=n;i++){
		scanf("%d",&t[i]);
		pack+=t[i]/tot;
		tc+=t[i]/tot;
		t[i]=t[i]%tot;
		sum+=t[i];
	}
	if(pack>=maxn)	return true;
	sum=sum/tot;//变成了能整个生产套餐数
	maxa=GetMin(sum*a,100);
	maxb=GetMin(sum*b,100);
	maxc=GetMin(sum*c,100);
	return false; 
}

inline bool Check(const int& i, const int& j, const int& k)
{
	int tmp=f[i][j][k];
	if(tmp>maxc){
		if((j<maxa&&(tmp-maxc)*p3>=p1) || (k<maxb&&(tmp-maxc)*p3)>=p2)
			return false;
	}
	return true;
} 

void Work()
{
	
	memset(f,-1,sizeof(f));
	f[0][0][0]=0;
	int tmp;
	for(int i=0;i<=n;i++){
		for(int j=0;j<=maxa;j++){
			for(int k=0;k<=maxb;k++){
				//if(Check(i-1,j,k)){
				if (f[i-1][j][k] < maxc) {
					for(int j2=j;j2>=0;j2--){
						tmp=(j-j2)*p1;
						if(tmp>t[i])	break;
						for(int k2=k;k2>=0;k2--){
							tmp=(j-j2)*p1+(k-k2)*p2;
							if(tmp<=t[i]&&f[i-1][j2][k2]!=-1)
								f[i][j][k]=GetMax(f[i][j][k],f[i-1][j2][k2]+tmp/p3);
						}		
					}
				}
				else 	f[i][j][k]=f[i-1][j][k];	
			}	
		}	
	}
	for(int j=0;j<=maxa;j++)
		for(int k=0;k<=maxb;k++)
			ans=GetMax(GetMin(j/a,GetMin(k/b,f[n][j][k])),ans);
			
	printf("%d",ans+tc);		
}

int main(){
	freopen("meal.in","r",stdin);
	freopen("meal.out","w",stdout);
	int in=Init();
	if(in==true){
		printf("%d",maxn);
		return 0;
	}
	Work();	
	return 0;
}