• 【9920】打包


    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    你现在拿到了许多的礼物,你要把这些礼物放进袋子里。你只有一个最多装下V 体积物品的袋子,你不能全部放进去。你也拿不动那
    么重的东西。你估计你能拿的最大重量为 G。现在你了解了每一个物品的完美值、重量和体积,你当然想让袋子中装的物品的完美值
    总和最大,你又得计划一下了。

    【输入格式】

    第一行:V 和 G 表示最大重量和体积。
    第二行:N 表示拿到 N 件礼物。
    第三到N+2行:每行3个数 Ti Vi Gi 表示各礼物的完美值、重量和体积

    对于20%的数据 N,V,G,Ti,Vi,Gi≤10
    对于50%的数据 N,V,G,Ti,Vi,Gi≤100
    对于80%的数据 N,V,G,Ti,Vi,Gi≤300
    80%到100%的数据是N,V,G,Ti,Vi,Gi≤380 的离散随机数据。

    【输出格式】

    输出共一个数,表示可能获得的最大完美值。

    Sample Input

    6 5
    
    4
    
    10 2 2
    
    20 3 2
    
    40 4 3
    
    30 3 3
    
    
    

    Sample Output

    50
    

    【题解】

    二维费用的0/1背包。

    给0/1背包的f数组增加一维

    f[i][j]表示花费1不超过i,花费2不超过j所能获得的最大完美值

    f[i][j] = max(f[i][j] , f[i-w1[m]][j-w2[m]]+ c[m]);

    记住0/1背包是逆序更新的就好了。

    【代码】

    #include <cstdio>
    #include <cstring>
    
    int mw1,mw2,n,c[400],w1[400],w2[400],f[400][400];
    
    void input_data()
    {
    	scanf("%d%d",&mw1,&mw2);
    	scanf("%d",&n);
    	for (int i = 1;i <= n;i++)
    		scanf("%d%d%d",&c[i],&w1[i],&w2[i]); //输入有两个花费的物品的信息 
    }
    
    void get_ans()
    {
    	memset(f,0,sizeof(f)); //初始化f数组为0 
    	for (int i = 1;i <= n;i++)
    		for (int j = mw1;j>=w1[i];j--) //枚举花费1和花费2  因为都是01背包所以都逆序。 
    			for (int k = mw2;k >=w2[i];k--)
    				if (f[j][k] < f[j-w1[i]][k-w2[i]] + c[i]) //如果能更新就更新 
    					f[j][k] = f[j-w1[i]][k-w2[i]] + c[i];	
    }
    
    void output_ans()
    {
    	printf("%d",f[mw1][mw2]);
    }
    
    int main()
    {
    	//freopen("F:\rush.txt","r",stdin);
    	input_data();
    	get_ans();
    	output_ans();
    	return 0;
    }


  • 相关阅读:
    利用Spark-mllab进行聚类,分类,回归分析的代码实现(python)
    c#项目返回文件案例
    设计模式 —— 组合模式
    设计模式 —— 备忘录
    设计模式 ——状态模式
    设计模式 —— 中介者模式
    设计模式 —— 适配器
    设计模式 —— 代理模式
    设计模式 ——门面模式
    设计模式 —— 享元模式
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632380.html
Copyright © 2020-2023  润新知