算法 | 0-1背包

  

#include<stdio.h>
#include<string.h>

#define MaxN  10000
#define MaxC  10000

int Val[MaxN][MaxN];

double binaryKnapsack(int numItems, int *w,int *v, int capacity)
{

    int i, j;

    for(i = 1; i <= numItems; ++i) {

    	for(j = 1; j <= capacity; j++) {
    		if(j < w[i-1]) {
    			Val[i][j] = Val[i-1][j];
				continue;
			}

			if( (Val[i-1][j-w[i-1]] + v[i-1]) >Val[i-1][j]) {

				Val[i][j] = (Val[i-1][j-w[i-1]] + v[i-1]);
			} else {
				Val[i][j] =  Val[i-1][j];
			}

		}

	}
	/**
    for (i = 0; i < numItems; ++i)
        for (j = capacity; j >= 0; j--)
            if (j >= w[i] && Val[j] < Val[j - w[i]] + v[i])
                Val[j] = Val[j - w[i]] + v[i];
    return Val[capacity]; **/

    return Val[numItems][capacity];
}

int main()
{
    int i, n, C, w[MaxN];
    int v[MaxN];
    int flag[MaxN];
    int ans;
    while (scanf("%d%d", &C, &n) != EOF)
    {
        for (i = 0; i < n; ++i)
            scanf("%d", &w[i]);
        for (i = 0; i < n; ++i)
            scanf("%d", &v[i]);

        ans = binaryKnapsack(n, w, v, C);
       printf("%d", ans);

        int j = C;
        memset(flag, 0, sizeof(flag));

        for(int i = n; i > 0; i-- ) {
        	if(Val[i][j] > Val[i-1][j]) {
        		flag[i] = 1;
        		j = j - w[i-1];
        		if(j < 0) break;
			}
		}

		for(int i = 1; i <= n; i++) {

				printf(" %d",flag[i]);

		}
		printf("\n");
    }

    return 0;
}

  

原文地址:https://www.cnblogs.com/jj81/p/9926480.html

时间: 2024-11-09 06:27:52

算法 | 0-1背包的相关文章

0-1背包的动态规划算法,部分背包的贪心算法和DP算法------算法导论

一.问题描述 0-1背包问题,部分背包问题.分别实现0-1背包的DP算法,部分背包的贪心算法和DP算法. 二.算法原理 (1)0-1背包的DP算法 0-1背包问题:有n件物品和一个容量为W的背包.第i件物品的重量是w[i],价值是v[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大.其中每种物品只有一件,可以选择放或者不放. 最优子结构性质:对于0-1问题,考虑重量至多W的最值钱的一包东西.如果去掉其中一个物品j,余下的必是除j以外的n-1件物品中,可以带走的重量

poj1417 带权并查集+0/1背包

题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 n 个询问,问某个神或魔(身份未知),问题是问某个是神还是魔,根据他们的回答,问是否能够确定哪些是神哪些是魔. 对于这些问题,我们只需要发现,如果回答对方是魔,那么即可以判断出这两个不是同一种族,而如果回答对方是神,那么说明这两个是同一种族,那么就可以用带权并查集合并这些神和魔,然后记录两种分别多少个,这样当所有询问都处理完时我们就可以得到一系列的集合,每个集合分别有它的两个种族的人数,但是此时对于每个

NOJ 1860 保研(0/1背包概率dp)

保研 时间限制(普通/Java):1000MS/3000MS         运行内存限制:65536KByte 总提交:171          测试通过:40 题目描述 对于一些名校而言,保研不仅可以由学校推免,也可以由学生自己向希望保研的学校提出申请,这个过程有点类似于外国学生向学校提交简历等待Offer的过程.但是,投递申请需要亲自去相应学校的研招办递交材料,这就需要一些成本(比如路费等),且每个院校都有自己的录取成功率.现在,请在总成本不超过限制的情况下,求出最大的成功率. 输入 输入

重拾算法(0)——目录

现在到了重拾基础算法,掌握算法思维的时候.暂定要学习的算法如下表. 1 算法 2 KMP 3 树 4 遍历二叉树 5 线索二叉树 6 霍夫曼树 7 图 8 深度优先搜索 9 广度优先搜索 10 最小生成树 11 最短路径 12 拓扑排序 13 关键路径 14 查找 15 线性表的查找 16 折半查找 17 树的查找 18 二叉排序树 19 平衡二叉树 20 B-树 21 B+树 22 散列表的查找 23 构造方法 24 处理冲突的方法 25 查找 26 排序 27 插入排序 28 直接插入排序

POJ 1636 Prison rearrangement DFS+0/1背包

题目链接: POJ 1636 Prison rearrangement Prison rearrangement Time Limit: 3000MS   Memory Limit: 10000K Total Submissions: 2194   Accepted: 984 Description In order to lower the risk of riots and escape attempts, the boards of two nearby prisons of equal

POJ 3628 Bookshelf 2 0/1背包和DFS两种解法

题目链接:POJ 3628 Bookshelf 2 Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7462   Accepted: 3436 Description Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled up quite quickly,

牛客网 TaoTao要吃鸡 ( 0/1背包变形 )

题意 : 题目链接 分析 :  如果没有 BUG (即 h == 0 的时候)就是一个普通的 0 / 1 背包 需要讨论一下 h != 0 的情况 此时有就相当于有物品是有特权的 而且背包装有特权的物品根据题目的要求是应当最后装的 也就是说特权物品装完之后背包将不再可装 所以特权物品肯定是只有一个的 数据量并不大,所以可以去枚举这个特权物品 那么如何知道在  没有装特权物品  之前的最佳选择方案? 答案就是用最小的可剩空间留给特权物品,然后其他空间去跑 0/1 背包 最小的可剩空间当然就是 h

浙大PAT CCCC L3-001 凑零钱 ( 0/1背包 &amp;&amp; 路径记录 )

题目链接 分析 : 就是一个 0/1 背包,但是需要记录具体状态的转移情况 这个可以想象成一个状态转移图,然后实际就是记录路径 将状态看成点然后转移看成边,最后输出字典序最小的路径 这里有一个很巧妙的做法 先将所有的硬币升序排序(这一点很重要) 然后在这一条件下,假设当前状态是考虑第 i 个硬币,前一个状态是考虑第 i-1 个硬币 试想对于同一个体积,如果选用的硬币数量越多是不是字典序更小 然后对于如果对于同一体积下,选用硬币数一样多的两种方案 由于我们已经升序排序,如果有一样多硬币的情况,那么

POJ 1745 【0/1 背包】

题目链接:http://poj.org/problem?id=1745 Divisibility Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13431   Accepted: 4774 Description Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequen

算法---分支限定0/1背包--蚁群算法

用蚁群算法解决01背包问题. 我本以为就是完全的蛮力法,但百度后觉得应该是这个 (4)分支限界-优先队列(STL) // #  分支限界优先队列法 //  队列中的节点类型 struct NodeType {//  分支限界节点 int no;     //  节点编号 int i;     //  当前节点在搜索空间的层次 int w;     //  当前节点的总重量 int v;     //  当前节点的总价值 int x[MAXN];           //  当前节点包含的解向量