zoukankan      html  css  js  c++  java
  • 【9926】完全背包

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中
    选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。

    【输入格式】

    第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);
    第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

    【输出格式】

    仅一行,一个数,表示最大总价值。

    Sample Input

    10 4
    2  1
    3  3
    4  5
    7  9
    
    【题解】
    【法一】
    设f[i][j]表示前i个物品,所用的容量不超过j所能获得的最大价值。
    f[i][j] = max{f[i-1][j],f[i-1][j-k*w[i]] + k*c[i]}; (k*w[i] <=j)
    对于第i个物品,可以选择不拿(f[i-1][j]),也可以任意选择k个。
    这种二维的存储方式比较容易理解。
    #include <cstdio>
    #include <cstring>
    
    int m,n,f[31][250],w[50],c[50];
    
    void input_data()
    {
    	scanf("%d%d",&m,&n);
    	for (int i = 1;i <= n;i++) //êäèë¸÷¸öÎïÆ·μÄDÅÏ¢ 
    		scanf("%d%d",&w[i],&c[i]);
    }	
    
    void get_ans()
    {
    	memset(f,0,sizeof(f));			 
    	for (int i = 1;i <= n;i++)
    		for (int j = m;j >= 0;j--)
    			{
    				f[i][j] = f[i-1][j];
    				int k = 1;
    				while (k*w[i] <= j)
    					{
    						if (f[i][j] < f[i-1][j-k*w[i]] + k*c[i])
    							f[i][j] = f[i-1][j-k*w[i]] + k*c[i];
    						k++;
    					}
    			}
    }
    
    void output_ans()
    {
    	printf("max=%d",f[n][m]);	
    }
    
    int main()
    {
    	//freopen("F:\rush.txt","r",stdin);
    	input_data();
    	get_ans();
    	output_ans();
    	return 0;	
    }
    【法二】
    设f[j]表示容量不超过j的背包所能装得的最大价值。
    f[j] = max{f[j],f[j-w[i]] + c[i]};
    这次j层循环要正向进行。
    假设一个物品的重量为1.
    你更新完f[5],又可以更新f[6],f[7]...这样就达到了每个物品可以多次拿的效果。
    #include <cstdio>
    #include <cstring>
    
    int m,n,f[250],w[50],c[50];
    
    void input_data()
    {
    	scanf("%d%d",&m,&n);
    	for (int i = 1;i <= n;i++) 
    		scanf("%d%d",&w[i],&c[i]);
    }	
    
    void get_ans()
    {
    	memset(f,0,sizeof(f));			 
    	for (int i = 1;i <= n;i++)
    		for (int j = w[i];j <= m;j++) //一定要正向循环。 
    			if (f[j-w[i]] + c[i] > f[j]) //这里就省掉了一层k循环。 
    				f[j] = f[j-w[i]] + c[i];
    }
    
    void output_ans()
    {
    	printf("max=%d",f[m]);	
    }
    
    int main()
    {
    	//freopen("F:\rush.txt","r",stdin);
    	input_data();
    	get_ans();
    	output_ans();
    	return 0;	
    }




  • 相关阅读:
    ThinkPHP5.0更改框架的验证方法:对象->validate(true)->save();
    ThinkPHP5.0版本和ThinkPHP3.2版本的区别
    ThinkPHP5.0版本的优势在于:
    11: django-haystack+jieba+whoosh实现全文检索
    10: supervisor进程管理工具
    09: redis集群之sentinel
    08: python支付宝支付
    07: redis分布式锁解决超卖问题
    06:keepalive高可用集群(新)
    05: 使用docker部署nginx负载均衡
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632395.html
Copyright © 2011-2022 走看看