zoukankan      html  css  js  c++  java
  • AT4120[ARC096D]Sweet Alchemy【贪心,背包】

    正题

    题目链接:https://www.luogu.com.cn/problem/AT4120


    题目大意

    给出\(n\)个物品和一个容量\(m\),第\(i\)个物品体积为\(c_i\)。除了第一个物品每个物品还有一个\(p_i(p_i<i)\)表示如果\(p_i\)个物品选择了\(x\)个,第\(i\)个物品选择了\(y\)个要求满足\(x\leq y\leq x+d\)

    \(1\leq n\leq 50,1\leq m,c_i\leq 10^9,0\leq d\leq 10^9,1\leq p<i\)


    解题思路

    一个简单的转换,变成一棵树之后选择就变为了一次必须选择一个子树。除了点\(1\)外其他最多就只能选择\(d\)次。

    就变成了一个多重背包,但是容量和体积很大,考虑贪心。因为价值都比较小,对于足够大的情况性价比贪心是对的,所以我们可以考虑先把小的直接做背包,大的贪心选。

    背包时每个物品最多选\(min\{n,d\}\)次,设\(f_i\)表示价值为\(i\)时的最小体积,然后枚举一个背包权值,剩下的贪心就好了。二进制分组或者单调队列优化多重背包都能过

    时间复杂度\(O(n^4\log n)\)


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long 
    using namespace std;
    const ll N=51;
    struct node{
    	ll w,v,id;
    }a[N];
    ll n,m,d,p[N],f[N*N*N],ans;
    bool cmp(node x,node y)
    {return x.v*y.w>y.v*x.w;}
    signed main()
    {
    	scanf("%lld%lld%lld",&n,&m,&d);
    	scanf("%lld",&a[1].w);a[1].v=1;a[1].id=1;
    	for(ll i=2;i<=n;i++)
    		scanf("%lld%lld",&a[i].w,&p[i]),a[i].v=1;
    	for(ll i=n;i>1;i--)
    		a[p[i]].w+=a[i].w,a[p[i]].v+=a[i].v,a[i].id=i;
    	ll mx=n*n*n;
    	memset(f,0x3f,sizeof(f));f[0]=0;
    	for(ll i=1;i<=n;i++){
    		ll x=min(n,d);
    		for(ll j=1;j<=x;j<<=1){
    			ll w=a[i].w*j,v=a[i].v*j;
    			for(ll k=mx;k>=v;k--)
    				f[k]=min(f[k],f[k-v]+w); 
    			x-=j;
    		}
    		if(!x)continue;
    		ll w=a[i].w*x,v=a[i].v*x;
    		for(ll k=mx;k>=v;k--)
    			f[k]=min(f[k],f[k-v]+w);
    	}
    	sort(a+1,a+1+n,cmp);
    	for(ll p=0;p<=mx;p++){
    		if(f[p]>m)break;
    		ll v=p,w=f[p],i=1;
    		for(i=1;i<n;i++){
    			if(a[i].id==1)break;
    			ll x=min(d-min(n,d),(m-w)/a[i].w);
    			w+=x*a[i].w;v+=x*a[i].v;
    		}
    		ll x=(m-w)/a[i].w;
    		w+=x*a[i].w;v+=x*a[i].v;
    		ans=max(ans,v); 
    	}
    	printf("%lld\n",ans);
    	return 0;
    }
    
  • 相关阅读:
    ElasticSearch记录(1)底层原理
    hbase学习记录(4)hbase和Hadoop整合(实现wrodcount程序)
    flume记录(2)监控文件和目录,对hdfs操作
    flume记录(1)使用
    hbase学习记录(3)JAVA_API操作hbase
    hbase学习记录(2)shell常用命令
    hbase学习记录(1)简介
    ssh三大框架整合
    spring事务管理
    Ubuntu 18.04版本设置root账户
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/14470284.html
Copyright © 2011-2022 走看看