• AOJ 完全背包 数量少体积大价值小版本 dp+贪心


    DPL_1_I

    n和v只有50 但体积很大。直接贪心明显过不了一些特殊的数据。

    考虑答案的构造 一堆大的+令一堆大的+...+几个数量少的。

    前面的肯定是按照贪心选的 对于数量少的可以直接dp。

    这里dp的阈值为50 这个阈值越大越精确 对于本题取50就可以(虽然不太明白这个阈值到底怎么算。

    也就是先利用价值进行dp 再贪心。减小时间和代码复杂度 使用二进制分组做多重背包。

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<ctime>
    #include<cctype>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 1000000000000000000ll
    #define inf 1000000001
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d\n",x)
    #define putl(x) printf("%lld\n",x)
    #define rep(p,n,i) for(int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define pii pair<int,int>
    #define mk make_pair
    #define P 1000000007ll
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-10
    #define sq sqrt
    #define S second
    #define F first
    #define mod 998244353
    #define v(x) t[x].v
    #define w(x) t[x].w
    #define m(x) t[x].m
    #define mx2(x) t[x].mx2
    #define max(x,y) ((x)<(y)?y:x)
    using namespace std;
    char *fs,*ft,buf[1<<15];
    inline char gc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=gc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
        return x*f;
    }
    const int MAXN=510,N=50*50*51;
    int n,W;
    ll f[N],ans;
    struct wy
    {
    	ll v,w,m;
    }t[MAXN];
    inline int cmp(wy a,wy b){return a.v*b.w>b.v*a.w;}
    int main()
    {
    	freopen("1.in","r",stdin);
    	n=read();W=read();
    	rep(1,n,i)v(i)=read(),w(i)=read(),m(i)=read();
    	
    	f[0]=0;int C=50*50*50;
    	rep(1,C,i)f[i]=INF;
    	
    	rep(1,n,i)
    	{
    		int ww=min(m(i),50ll);
    		m(i)-=ww;
    		for(int k=1;;k=k<<1)
    		{
    			if(k>ww)break;
    			for(int j=C;j>=k*v(i);--j)f[j]=min(f[j],f[j-k*v(i)]+k*w(i));
    			ww-=k;
    		}
    		for(int j=C;j>=ww*v(i);--j)f[j]=min(f[j],f[j-ww*v(i)]+ww*w(i));
    	}
    	
    	sort(t+1,t+1+n,cmp);
    	
    	rep(0,C,i)
    	{
    		if(f[i]==INF||f[i]>W)continue;
    		ans=max(ans,i);
    		int W1=W-f[i];
    		ll ANS=i;
    		rep(1,n,j)
    		{
    			int cc=min(W1/w(j),m(j));
    			ANS+=cc*v(j);
    			W1-=cc*w(j);
    		}
    		ans=max(ans,ANS);
    	}
    	
    	printf("%lld\n",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    MessageFormat理解,MessageFormat.format(Object obj)方法
    正则表达式
    数字处理类
    包装类
    遍历Map的4种方法(来自网络)
    集合类
    数组
    字符串
    语言基础
    Linux下使用openssl加解密
  • 原文地址:https://www.cnblogs.com/chdy/p/16647560.html
Copyright © 2020-2023  润新知