链接;点击打开链接
题意:有n种甜点,每种都有三个属性(能量,空间,数目),有m辆卡车,每种都有是三个属性(空间,花费,数目),问至少运输p能量的甜点,花费最小是多少
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int n,m,p;
int dp[2000005];
int t[205],u[205],v[205];
int x[205],y[205],z[205];
int main(){
int i,j,k,ans,num,tmp,cas,sol,sign;
scanf("%d",&cas);
while(cas--){
scanf("%d%d%d",&n,&m,&p);
for(i=0;i<n;i++)
scanf("%d%d%d",&t[i],&u[i],&v[i]);
for(i=0;i<m;i++)
scanf("%d%d%d",&x[i],&y[i],&z[i]);
memset(dp,INF,sizeof(dp));
dp[0]=0;
for(i=0;i<n;i++){ //两次多重背包
num=v[i]; //因为每个糖的能量最大是100,因此上限并不用很大
for(j=1;num>0;j<<=1){
tmp=min(j,num);
for(k=60000;k>=tmp*t[i];k--)
dp[k]=min(dp[k],dp[k-tmp*t[i]]+tmp*u[i]);
num-=tmp;
}
}
ans=INF;
for(i=p;i<=60000;i++){
if(dp[i]!=INF)
ans=min(ans,dp[i]);
} //求出满足能量p的最小体积
if(ans==INF){
puts("TAT");
continue;
}
memset(dp,0,sizeof(dp));
for(i=0;i<m;i++){ //以价格为背包,再做一遍多重背包
num=z[i];
for(j=1;num>0;j<<=1){
tmp=min(j,num);
for(k=60000;k>=tmp*y[i];k--)
dp[k]=max(dp[k],dp[k-tmp*y[i]]+tmp*x[i]);
num-=tmp;
}
}
sign=0;
for(i=1;i<=60000;i++)
if(dp[i]>=ans&&dp[i]!=INF){
sign=1;
break;
}
if(sign==1)
printf("%d\n",i);
else
puts("TAT");
}
return 0;
}