zoukankan      html  css  js  c++  java
  • 背包问题

    Luogu1855 榨取kkksc03

    每个愿望需要金钱(m_i) , 时间(t_i) . 求最多能满足多少个愿望

    很好的例题 : 01背包 : 从大往小选 , 详见代码
    即对于每个物品都直接更新 , 但顺序是从大到小以避免重复.

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define Debug(x) cout<<#x<<"="<<x<<endl
    using namespace std;
    typedef long long LL;
    const int INF=1e9+7;
    inline LL read(){
        register LL x=0,f=1;register char c=getchar();
        while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
        while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
        return f*x;
    }
    
    int m[105],t[105],dp[205][205],n,M,T;
    
    int main(){
    	n=read(),M=read(),T=read();
    	for(int i=1;i<=n;i++){
    		m[i]=read(),t[i]=read();
    		for(int j=M;j>=m[i];j--){
    			for(int k=T;k>=t[i];k--)
    				dp[j][k]=max(dp[j][k],dp[j-m[i]][k-t[i]]+1);
    		}
    	}
    	printf("%d
    ",dp[M][T]);
    }
    

    Luogu1417 烹调方案

    一共有(n)件食材,每件食材有三个属性,(a_i)(b_i)(c_i),如果在(t)时刻完成第(i)样食材则得到(a_i-t*b_i)的美味指数,用第(i)件食材做饭要花去(c_i)的时间 , 求在时间(T)内能获得最大美味指数.

    现在考虑相邻的两个物品(x,y).假设现在已经耗费(t)的时间,那么分别列出先做(x,y)的代价:
    (a[x]-(t+c[x])*b[x]+a[y]-(t+c[x]+c[y])*b[y]dots)
    (a[y]-(t+c[y])*b[y]+a[x]-(t+c[y]+c[x])*b[x]dots)
    对这两个式子化简,得到①>②的条件是(c[y]*b[x]>c[x]*b[y])

    然后按照顺序(01)背包的选法来选.

    后加入的时间在后面 , 所以需要排序
    排好序还要再选背包?考虑当前空间下怎么选最优

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define Debug(x) cout<<#x<<"="<<x<<endl
    using namespace std;
    typedef long long LL;
    const int INF=1e9+7;
    inline LL read(){
        register LL x=0,f=1;register char c=getchar();
        while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
        while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
        return f*x;
    }
    
    const int N=55;
    const int M=100005;
    
    struct Node{
        int a,b,c;
    }a[N];
    inline bool cmp(const Node& x,const Node& y){
        return 1ll*x.b*y.c>1ll*y.b*x.c;
    }
    
    LL f[M],ans=-INF;
    int T,n;
    
    int main(){
        T=read(),n=read();
        for(int i=1;i<=n;i++) a[i].a=read();
        for(int i=1;i<=n;i++) a[i].b=read();
        for(int i=1;i<=n;i++) a[i].c=read();
        sort(a+1,a+n+1,cmp);
        memset(f,0xcf,sizeof f);
        f[0]=0;
        for(int i=1;i<=n;i++){
            for(int j=T-a[i].c;j>=0;j--)
                if(f[j]!=-1)
                    f[j+a[i].c]=max(f[j+a[i].c],f[j]+(LL)a[i].a-(LL)(j+a[i].c)*a[i].b);
    				//后加入的时间在后面,所以需要排序
    				//排好序还要再选背包?考虑当前空间下怎么选最优
        }
        for(int i=0;i<=T;i++)
            ans=max(ans,f[i]);
        printf("%lld
    ",ans);
    }
    

    Luogu1474 货币系统

    给定(n)种货币 , 求组成面值(m)的方案数 .
    直接对于每一个新加进来的数 , 它可以对所有数产生影响,即(f[j]+=f[j-a[i]]) .
    这里是完全背包 , 每种面值可以选无限次 , 所以循环顺序从小到大 .

    #include<iostream>
    using namespace std;
    long long f[100005];
    int a[31],n,m;
    int main(){
    	cin>>n>>m;
    	f[0]=1;
    	for(int i=1;i<=n;i++){
    		cin>>a[i];
    		for(int j=a[i];j<=m;j++)
    			f[j]+=f[j-a[i]];
    	}
    	cout<<f[m]<<endl;
    }
    
  • 相关阅读:
    Differential Geometry之第六章平面曲线的整体性质
    球盒问题
    Fiddler (二) Script 用法
    Mac下使用Fiddler
    更新mac自带的python
    在Linux里设置环境变量的方法(export PATH)
    关于null和undefined
    ANE在ios上的使用流程和问题解决
    starling 笔记
    Android SDK安装时碰到的问题之解决办法
  • 原文地址:https://www.cnblogs.com/lizehon/p/10940269.html
Copyright © 2011-2022 走看看