• [bzoj3717][PA2014]Pakowanie_动态规划_状压dp


    Pakowanie bzoj-3717 PA-2014

    题目大意:给你n个物品m个包,物品有体积包有容量,问装下这些物品最少用几个包。

    注释:$1le nle 24$,$1le mle 100$


    想法:以为是什么超级牛逼的背包dp,结果就是状压dp

    状态:f[s]表示装s状态的物品需要多少背包,g[s]表示在f[s]的前提下,最大的背包剩余的容量。

    转移:直接判断最后一个能不能装下当前物品,转移即可。

    还有就是这个题卡常,只能直接用Lowbit枚举1,不能全枚举,会T... ...

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 17000000 
    #define lowbit(x)   (x&(-x))
    using namespace std;
    int n,m,tmp;
    int f[N],g[N],a[N],c[101];
    bool cmp(const int &a,const int &b){return a>b;}
    int main()
    {
    	scanf("%d%d",&n,&m); int sum=(1<<n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	for(int i=1;i<=m;i++) scanf("%d",&c[i]); sort(c+1,c+m+1,cmp);
    	for(int i=n;i;i--) a[(1<<(i-1))]=a[i];
    	for(int i=1;i<sum;i++)
    	{
    		f[i]=m+1;g[i]=-1;
    		for(int j=i;j;j-=tmp)
    		{
    			tmp=lowbit(j);int x=i-tmp;
    			if(a[tmp]<=g[x]&&(f[x]<f[i]||(f[x]==f[i]&&g[x]-a[tmp]>g[i])))
    				f[i]=f[x],g[i]=g[x]-a[tmp];
    			else if((f[x]+1<f[i]||(f[x]+1==f[i]&&c[f[x]+1]>g[i]+a[tmp]))&&c[f[x]+1]>=a[tmp])
    				f[i]=f[x]+1,g[i]=c[f[i]]-a[tmp];
    		}
    	}
    	if(f[sum-1]>m) puts("NIE");
    	else printf("%d
    ",f[sum-1]);
    	return 0;
    }
    

    小结:好题,虽然卡常... ...

  • 相关阅读:
    表连接问题
    public interface Serializable?标记/标签接口
    4.21
    第十周周记
    测试
    第九周周记
    第七周周记
    fighting.
    fighting
    作业一
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9375027.html
Copyright © 2020-2023  润新知