题目大意

[1.26] T3-食物

题目解析

首先很容易发现,食物的美味度和运输的最小花费是毫无关系的

而有关求出食物的美味度的变量有:n种食物,第i种食物的大小ui,共有vi份,以及美味度ti

很明显的是一个多重背包

设f[i]表示当大小为i时的最大美味度

由于多重背包变01包时,一个一个拆分太慢,这里使用二进制优化

求出最大美味度是否大于p,

是,则求出满足p的最小的重量,记下该最小重量W,不是,则输出“TAT”

接着就是运输的最小花费

而有关求出运输的最小花费的变量有:m种运输工具,第i种运输一次的费用yi,共有zi种,以及工具运输的大小xi

很明显还是一个多重背包,求法和上文一样

最后求出当重量>=W时的最小花费,输出即可

代码

#include<bits/stdc++.h>
using namespace std;
int T,n,m,p,ans,W;
int value[20010],weight[20010],f[50010];
struct A

{
	int x,y,z;
}a[205],b[205];
int read()
{
	int x=0;
	char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-48,c=getchar();
	return x;
}
int main()
{
	T=read();
	while(T--)
	{
	  n=read();m=read(),p=read();
	  for(int i=1;i<=n;i++)
	   a[i].x=read(),a[i].y=read(),a[i].z=read();
	  for(int i=1;i<=m;i++)
	   b[i].x=read(),b[i].y=read(),b[i].z=read();
	  
	  int sum=0,cnt=0;
	  for(int i=1;i<=n;i++)
	  {
	  	cnt=1;
	  	while(a[i].z>cnt)
	  	{
	  	  a[i].z-=cnt;
	  	  value[++sum]=cnt*a[i].x;
	  	  weight[sum]=cnt*a[i].y;
	  	  cnt<<=1;
		}
		value[++sum]=a[i].z*a[i].x;
		weight[sum]=a[i].z*a[i].y;
	  }
	  memset(f,0,sizeof(f));
	  for(int i=1;i<=sum;i++)
	   for(int j=20000;j>=weight[i];j--)
	    f[j]=max(f[j],f[j-weight[i]]+value[i]);
	  W=0;
	  for(int i=1;i<=50000;i++)
	   if(f[i]>=p)
	   {
	   	 W=i;
	   	 break;
	   }
	  if(!W)
	  {
	  	cout<<"TAT"<<endl;
	  	continue;
	  }
	  
	  memset(f,0,sizeof(f));
	  sum=0,cnt=0;
	  for(int i=1;i<=n;i++)
	  {
	  	cnt=1;
	  	while(b[i].z>cnt)
	  	{
	  	  b[i].z-=cnt;
	  	  value[++sum]=cnt*b[i].x;
	  	  weight[sum]=cnt*b[i].y;
	  	  cnt<<=1;
		}
		value[++sum]=b[i].z*b[i].x;
		weight[sum]=b[i].z*b[i].y;
	  }
	  memset(f,0,sizeof(f));
	  for(int i=1;i<=sum;i++)
	   for(int j=50000;j>=weight[i];j--)
	    f[j]=max(f[j],f[j-weight[i]]+value[i]);
	  ans=0;
	  for(int i=1;i<=50000;i++)
	   if(f[i]>=W)
	   {
	   	 ans=i;
	   	 break;
	   }
	  if(!ans)
	  {
	  	cout<<"TAT"<<endl;
	  	continue;
	  }
	  cout<<ans<<endl;
	}
}

相关文章: