zoukankan      html  css  js  c++  java
  • 【JZOJ4224】食物【背包】

    题目大意:

    题目链接:https://jzoj.net/senior/#main/show/4224
    在这里插入图片描述


    思路:

    由于食物可以拆开运输,所以让食物美味度之和不小于p最少的价钱运输这两个问是毫不相关的。
    那么就分开来看。nn种不同的食物,美味度tit_i,大小uiu_i,数量viv_i,这不就是一道裸的完全背包吗!
    fif_i表示重量为ii的最大美味度,那么就可以用二进制拆分做出来前半问了。


    mm种运载工具,载重xix_i,费用yiy_i,运输次数ziz_i。。。
    这和第一问有什么区别嘛。。。
    还是一个完全背包。跑一遍就可以得到答案了。
    注意判断TATTAT的情况。


    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N=210;
    const int M=50200;
    int T,n,m,p,q,sum,ans,t[N],u[N],v[N],f[M],W[N*7],V[N*7];
    
    int read()
    {
    	int d=0;
    	char ch=getchar();
    	while (ch<'0'||ch>'9') ch=getchar();
    	while (ch>='0'&&ch<='9')
    		d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    	return d;
    }
    
    int main()
    {
    	T=read();
    	while (T--)
    	{
    		memset(V,0,sizeof(V));
    		memset(W,0,sizeof(W));
    		memset(f,0,sizeof(f));
    		sum=0;
    		n=read(),m=read(),p=read();
    		for (register int i=1;i<=n;i++)
    		{
    			t[i]=read(),u[i]=read(),v[i]=read();
    			int j;
    			for (j=1;j<=v[i];j*=2)  //二进制拆分
    			{
    				V[++sum]=t[i]*j;
    				W[sum]=u[i]*j;
    				v[i]-=j;
    			}
    			if (v[i])
    			{
    				V[++sum]=t[i]*v[i];
    				W[sum]=u[i]*v[i];
    			}
    		}
    		for (register int i=1;i<=sum;i++)
    			for (register int j=M-1;j>=W[i];j--)
    				f[j]=max(f[j],f[j-W[i]]+V[i]);
    		q=-1;
    		for (register int i=1;i<M;i++)
    			if (f[i]>=p)  //求出满足美味度不小于p的最小价值
    			{
    				q=i;
    				break;
    			}
    		if (q<0)  //不成立
    		{
    			printf("TAT
    ");
    			for (int i=1;i<=m;i++) q=read(),q=read(),q=read();
    			//一定要把无用的读入读完!!!
    			continue;
    		}
    		
    		/////////////////////////////////////////////////////////////////////
    		
    		memset(V,0,sizeof(V));
    		memset(W,0,sizeof(W));
    		memset(f,0,sizeof(f));
    		sum=0;
    		for (register int i=1;i<=m;i++)
    		{
    			t[i]=read(),u[i]=read(),v[i]=read();
    			int j;
    			for (j=1;j<=v[i];j*=2)
    			{
    				V[++sum]=t[i]*j;
    				W[sum]=u[i]*j;
    				v[i]-=j;
    			}
    			if (v[i])
    			{
    				V[++sum]=t[i]*v[i];
    				W[sum]=u[i]*v[i];
    			}
    		}
    		for (register int i=1;i<=sum;i++)
    			for (register int j=50000;j>=W[i];j--)  //最大花费50000
    				f[j]=max(f[j],f[j-W[i]]+V[i]);
    		ans=-1;
    		for (register int i=1;i<=50000;i++)
    			if (f[i]>=q)
    			{
    				ans=i;
    				break;
    			}
    		if (ans<0)
    		{
    			printf("TAT
    ");
    			continue;
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Jquery Plugin模版
    jquery之extend
    java反射技术实例
    java基础汇总
    Java学习路线
    java的一个爬虫
    Java深度理解——Java字节代码的操纵
    java编程思想-基础
    hdu 5201 The Monkey King【容斥原理+组合数学】
    容斥原理
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998348.html
Copyright © 2011-2022 走看看