背包问题[穷举法]

/*-------------完整代码@映雪-------------*/

#include <iostream>
using namespace std;
typedef struct goods
{
    double *value; //价值
    double *weight; //重量
    int num;//物品数量
    int limitw; //限制重量
}GOODS;
int binadd(char select1[],int n) //二进制运算
{
    int i,carry=0;
    select1[0] += 1;
    for (i = 0; i < n; i++)
    {
        select1[i] += carry; //加上进位
        carry = select1[i] /2;//计算进位
        select1[i] %= 2; //保留0或1;
        if (carry==0)
            return 0;
    }
    return carry;
}
void backpack(GOODS *g,char select[])
{
   int i,flag;
   char *select1;
   double maxvalue = 0,tw,tv;
   if(!(select1 = (char *)malloc(g->num)))//保存最后加入背包的物品序号
   {
       printf("内存分配失败\n");
       exit(0);
   }
   for (i = 0; i < g->num; i++)//将数组清空
       select1[i] = 0;
   while(binadd(select1, g->num) == 0) //进行一次二进制加法运算
   {
       tw = 0;
       tv = 0;
       flag = 1;
       printf("\n");
       for (i = 0; i < g->num; i++) //根据选中状态进行试算
       {
           if (select1[i] == 1) //若选中该物品
           {
               tw += g->weight[i]; //累加选中物品的重量
               tv += g->value[i];//累加选中物品的价值
               if (tw > g->limitw) //若重量超过限制
               {
                   flag = 0;
                   break; //退出本次方案的试算
               }
           }
       }
       if(flag && maxvalue < tv) //若方案选中物品重量未超过限制,并且本方案累加价值大于已有方案的最大价值
       {
           maxvalue = tv;
           for(i = 0; i < g->num; i++) //保存方案
               select[i] = select1[i];
       }
   }
}

int main()
{
   double sumweight,maxvalue; //用来保存阶段最优价值
   char *select;
   GOODS g;
   int i; //item数组用来保存最后放入背包物品的序号
   printf("背包最大重量:");
   scanf("%d",&g.limitw);
   printf("可选物品数量:");
   scanf("%d",&g.num);
   if(!(g.value = (double *)malloc(sizeof(double)*g.num)))//分配内存保存物品价值
   {
       printf("内存分配失败\n");
       exit(0);
   }
   if(!(g.weight = (double *)malloc(sizeof(double)*g.num)))//分配内存保存物品的重量
   {
       printf("内存分配失败\n");
       exit(0);
   }
   if(!(select = (char *)malloc(sizeof(char)*g.num)))
    {   printf("内存分配失败\n");
       exit(0);
   }
   for (i = 0; i < g.num; i++)
   {
      printf("输入第%d号物品的重量和价值:",i + 1);
      scanf("%lf%lf",&g.weight[i],&g.value[i]);
   }
   printf("\n背包最大能装的重量为:%d\n\n",g.limitw);
   for (i = 0; i < g.num; i++)
      printf("第%d号物品重:%.2f,价值:%.2f\n", i + 1, g.weight[i], g.value[i]);
   backpack(&g,select);
   sumweight=0;
   maxvalue=0;
   printf("\n可将以下物品装入背包,使背包装的物品价值最大:\n");
   for (i = 0; i < g.num; ++i)
      if (select[i])
      {
         printf("第%d号物品,重量:%.2f,价值:%.2f\n", i + 1, g.weight[i], g.value[i]);
         sumweight+=g.weight[i];
         maxvalue+=g.value[i];
      }
   printf("\n总重量为: %.2f,总价值为:%.2f\n", sumweight, maxvalue );
   return 0;
}

完整代码

时间: 2024-10-16 08:52:59

背包问题[穷举法]的相关文章

C#跳转语句 迭代法 穷举法

一.跳转语句 break & continue break:跳出循环,终止此循环,不管下面还有多少次,全部跳过. string a=" ", for (int i=1;i<=10;I++) { if(i==5) { break; } a += i +",": } Console.WriteLine(a); 输出结果为 1,2,3,4,5 continue:终止此次循环,直接开始下次循环. string a=" ", for (int

什么叫穷举法?

穷举法的基本思想是根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕.若某个情况验证符合题目的全部条件,则为本问题的一个解:若全部情况验证后都不符合题目的全部条件,则本题无解.穷举法也称为枚举法. 用穷举法解题时,就是按照某种方式列举问题答案的过程.针对问题的数据类型而言,常用的列举方法一有如下三种: (1)顺序列举 是指答案范围内的各种情况很容易与自然数对应甚至就是自然数,可以按自然数的变化顺序去列举. (2)排列列举 有时答案的数据形式是一组数的

15-07-03 语句- for () 循环语句-穷举法

for()  穷举法 用循环把各种可能的情况都走一遍,然后用if条件把满足要求的结果给筛选出来. 例如:1.找100以内的偶数 for (int i = 0; i <= 100; i++) { if (i % 2 == 0) { Console.WriteLine(i); } } 2.小明单位发了50元的购物卡,他到超市买洗化用品,一是牙刷(5元),二是香皂(2元),三是牙膏(10元)怎么可以正好把五十元花完. for (int ys = 0; ys <= 10; ys++) { for (i

for循环的应用:迭代法和穷举法

for()循环.四要素:初始条件,循环条件,状态改变,循环体.执行过程:初始条件--循环条件--循环体--状态改变--循环条件....注意:for的小括号里面分号隔开,for的小括号后不要加分号.for的嵌套.应用:迭代法,穷举法.一.迭代法:有一定规律. 每次循环都是从上次运算结果中获得数据,本次运算的结果都是要为下次运算做准备. 二.穷举法:用循环把各种可能的情况都给走一遍,然后用if条件把满足要求的结果给筛选出来.

穷举法

穷举法是一种用来暴力破解某些数字组合时候用到的一种方法. 实际应用呢,例如:列举一个三位数,是11的倍数,且个位.十位.百位不相等. 代码: #include<iostream> using namespace std; int main() { int i; cout<<"11的倍数,且个位十位百位不相等:"<<endl; for (i=100; i<1000; i++) { //个位 int g = i%10; //十位 int s = i

算法基础一 穷举法

/*穷举法*/ /*鸡兔同笼35头,94足,鸡兔各几只?*/ #include<stdio.h> const int Num = 35; const int Foots = 94; int main() { int cN;//鸡 int rN;//兔 for (cN = 0; cN <= 35; cN++) { rN = Num - cN; if (Foots == cN * 2 + rN * 4 ) { printf("鸡:%d,兔:%d\n",cN,rN); }

XTU OJ 1175 Hurry Up(三分法&amp;&amp;穷举法)

 Hurry Up Accepted : 88   Submit : 345 Time Limit : 1000 MS   Memory Limit : 65536 KB Problem Description GG is some what afraid of his MM. Once his MM asks, he will always try his best to rush to their home. Obvious, he can run home in straight li

2017.02.24C# 跳转语句,迭代法,穷举法,异常语句处理。

一,跳转语句(1)break: 代码: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace @break 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 Int32 a = 0; 13 for(a=0;a<25;a++) 14 { 15 Consol

迭代法和穷举法

迭代法:每次循环都要把某一个或多个变量不断放大,为的是下一次循环可以继续使用,最后达到最终的大小.代表性的题:1.累加求和2.阶乘3.折纸int sum = 0;for(int i=1;i<=10;i++){ sum += i;} 穷举法:将所有的可能性都走一遍,然后判断符合条件的可能性,单独拿出来.基本用法:int count = 0;for (int i = 1; i <= 15; i++) //1分的硬币{ for (int j = 1; j <= 7; j++)//2分的硬币 {