题目大意
题目解析
首先很容易发现,食物的美味度和运输的最小花费是毫无关系的
而有关求出食物的美味度的变量有: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;
}
}