背包问题

WX[i-1]=W[h];

装箱问题 P1133

背包问题动态规划_背包问题动态规划伪代码背包问题动态规划_背包问题动态规划伪代码


背包问题动态规划_背包问题动态规划伪代码


i,j,v,n,x:longint;

f:array[0..20001] of boolean;

begin

readln(v,n);

for i:=1 to n do f[i]:=false;

f[0]:=true;

for i:=1 to n do begin

readln (x);

for j:=v-x downto 0 do

if f[j] Then f[j+x]:=true;

end;

i:=v;

while (i>0)

and not f[i]

do i:=i-1;

wrin(v-i);

end.

采 P1104

i,j,n,t,x,m:longint;

s:array[0..20001] of longint;

begin

readln(t,n);

for i:=1 to n do

begin

readln (x,m);

if x<=t then

for j:=t downto x do

if s[j-x]+m>s[j] Then s[j]:=s[j-x]+m;

end;

write(s[t])

end.

f:array[0..1002] of longint;

begin

readln (n);

readln (t);

for i:=1 to n do begin

readln (fi,ti);

if ti<=t then begin

for j:=t downto ti do

end;

end;

wrin (f[t]);

end.

开心的金明 P1317

i,j,n,t,x,m:longint;

s:array[0..30000] of longint;

begin

readln(t,n);

for i:=1 to n do

begin

readln (x,m);

if x<=t then

for j:=t downto x do

if s[j-x]+mx>s[j] Then s[j]:=s[j-x

]+mx;

end;

wrin (s[t]);

end.

NASA的食物 P1334

var m,v,n,i,mi,vi:integer;

mm,vv,kk:array[1..50] of integer;

f:array[0..400,0..400] of integer;

begin

readln(v,m);

readln(n);

for i:=1 to n do readln(vv[i],mm[i],kk[i]);

fillchar(f,sizeof(f),0);

for i:=1 to n do

for vi:=v downto vv[i] do

fotype ar=array[1..maxn] of integer;r mi:=m downto mm[i] do

if f[vi,mi]

f[vi,mi]:=f[vi-vv[i],mi-mm[i]]+kk[i];

wrin(f[v,m]);

end.

C++有关0--1 背包问题

小飞侠的游园方案 P1025

不是很懂,不过找到了一个与你这个问题有关的算法,希望有帮助

for(int j=w[i];j<=c;j++) m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);

DKNAP(p2,w2,M2,n2)

float p2[],w2[];

float M2;

int n2;

int F[10],x[10];

float P[1000],W[1000],pp,ww,PX[10],WX[10],PY[10],c;

F[0]=1;

P[1]=W[1]=0;

l=h=1;

F[1]=next=2;

for (i=1; i<=n2; i++)

{k=l;

r=l;

{if (W[r]+w2[i]<=M2) r++;

else break;

}u=r-1;

for (j=1; j<=u; j++)

{pp=P[j]+p2[i];

ww=W[j]+w2[i];

while (k<=h && W[k]

{P[next]=P[k];

W[next]=W[k];

next++;

k++;

}if (k<=h && W[k]==ww)

{pp=max(pp,P[k]);

k++;

}if (pp>P[next-1])

{P[next]=pp;

W[next]=ww;

next++;

}while (k<=h && P[k]<=P[next-1]) k++;

}while (k<=h)

{P[next]=P[k];

W[next]=W[k];

next++;

k++;

}//对Si+1置初值

PX[i-1]=P[h];

l=h+1;

h=next-1;

}c=M2;

for (i=n2-1; i>=0;i--)

{j=F[i];

while (j<=F[i+1]-1)

{if (W[j]+w2[i+1]<=c) j++;

else break;

}u=j-1;

if (u

else PY[i]=P[u]+p2[i+1];

if (PX[i]>PY[i]) x[i+1]=0;

else {x[i+1]=1; c=c-w2[i+1];}

//printf("%d",x[i+1]);

//printf("n");

}printf("0-1背包问题动态规划方法的解x(n)如下:n");

for (i=1;i<=n2;i++)

printf("%4d",x[i]);

printf("n");

}/////////////////////////////////////////////

BKNAP(p3,w3,M3,n3)

float p3[],w3[],M3;

int n3;

{int k,i,j,y[10],x[10],b[10];

float cw,cp,fp,fw,a[10],s,t;

for (i=1;i<=n3;i++)

{a[i]=p3[i]/w3[i];

b[i]=i;

}for (j=1;j<=n3-1;j++)

{for (i=1;i<=n3-j;i++)

{s=a[i];a[i]=a[i+1];a[i+1]=s;

t=b[i];b[i]=b[i+1];b[i+1]=t;

};

}for (i=1;i<=n3;i++)

printf("%4dn",b[i]);

printf("n");

cw=cp=0;

k=1;

fp=-1;

for (k=1;;k++)

{while (k<=n3 && cw+w3[k]<=M3)

{cw+=w3[k];

cp+=p3[k];

y[k]=1;

k++;

}if (k>n3)

{fp=cp;

fw=cw;

k=n3;

for (i=1;i<=k;i++)

x[b[i]]=y[i];

break;

}else y[k]=0;

while (bound(cp,cw,k,M3,n3,w3,p3)<=fp)

{while (k!=0 && y[k]!=1)

k-=1;

if (k==0) return;

y[k]=0;

cw-=w3[k];

cp-=p3[k];

}}

printf("0-1背包问题回溯方法的解x(n)如下:n");

for (i=1; i<=n3; i++)

{//j=b[i];

printf("%4d",x[i]);

}printf("n");

printf("%4f,%4f",fp,fw);

printf("n");

}float bound(zp,zw,k,M4,n4,ww,pp)

float zp,zw,M4,ww[],pp[];

int k,n4;

{int i;

float b,c;

b=zp;c=zw;

for (i=k+1;i<=n4;i++)

{c+=ww[i];

if (c<=M4) b+=pp[i];

}return (b);

}

就两个算法,一个++,一个比较。建议做子函数

收藏了

背包问题的发展历程及研究现状

鉴于数目不大,可以用穷举法

背包问题是组合优化学科中一个经典而的问题,它的研究价值不言而喻,吸引了众多专家学者从各个角度开展对其的研究工作,各种算法设计思想也应运而生。由于背包问题的NP完全性,如何在算法的时间效率和求解精度上取得有效的平衡,成为背包问题算法设计主要的考虑因素。数据挖掘是近几年信息领域发展最快的技术之一。由于数据挖掘具有强大的发现有用知识的功能,可以利用它来发现背包问题解的相似的状态空间,然后进行约减,从而克服背包问题的NP困难性。

背包问题,是用来介绍动态规划算法最经典的例子,网上关于01背包问题的讲解也很多,我写这篇文章力争做到用最简单的方式,最少的公式把01背包问题讲解透彻。

01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }

f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的价值。

Pi表示第iF[i+1]=next;件物品的价值。

决策:为了背包中物品总价值化,第 i件物品应该放入背包中吗 ?

请问背包问题的时间复杂度不是一个多项式时间复杂度如何解释?

题:

背包问题动态规划解决的时间复杂度应该是O(2^n)吧。把整个问题构造一个满二叉树,每一层的表示第i个物品,比如从顶点出发,顶点表示个物品,若选择左支,表示选中个物品,右支表示没有选中个物品,以此类推,这样从顶点到叶子的一条路径就是最终的一个整体选择过程,在过程中可以判定选中现有物品是否满足给定条件。实际是暴利算法,把所有可能情况穷举了一遍。由于树是N层的满二叉树,所以时间复杂度是O(2^n)。这已经成指数次增长了,不能算多项式时间复杂度。

典型的算法:Prim算法和Kruskal算法

贪心算法 双背包问题 就是有两个背包的贪心算法 谁知道啊 急求

memset(b,0,sizeof(b));

贪心算法是在局部保持,一直保持,直到全局。

------------

背包问题,是动态规划吧- -if (a[i]

也没听过你说的什么双背包问题,应该是二维背包吧,基本什么没什么区别,就是状态数组加多一维,求解的时候加多一维。

01背包问题怎么做?(我是小学生啦,简单讲解写吧,我要参加noip!) 我是爱联学生。

设 f(x)表示重量不超过x公斤的价值,

初看这类问题,个想到的会是贪心,但是贪心法却无法保证一定能得到解,看以下实例:

贪心准则1:从剩余的物品中,选出可以装入背包的价值的物品,利用这种规则,价值的物品首先被装入(设有足够容量),然后是下一个价值的物品,如此继续下去。这种策略不能保证得到解。例如,考虑n=2, w=[100,10,10], p =[20,15,15], c =105。当利用价值贪婪准则时,获得的解为x= [1,0,0],这种方案的总价值为20。而解为[0,1,1],其总价值为30。

贪心准则2:从剩下的物品中选择可装入背包的重量最小的物品。虽然这种规则对于前面的例子能产生解,但在一般情况下则不一定能得到解。考虑n= 2 ,w=[10,20], p=[5,100], c= 2 5。当利用重量贪婪策略时,获得的解为x =[1,0], 比解[ 0 , 1 ]要。

贪心准则3:价值密度pi /wi 贪婪算法,这种选择准则为:从剩余物品中选择可 装入包的pi /wi 值的物品,但是这种策略也不能保证得到解。利用此策略解 n=3 ,w=[20,15,15], p=[40,25,25], c=30 时的得到的就不是解。

由此我们知道无法使用贪心算法来解此类问题。我们采用如下思路:

在该问题中需要决定x1 .. xn的值。设按i = 1,2,...,n 的次序来确定xi 的值。如果置x1 = 0,则问题转变为相对于其余物品(即物品2,3,.,n),背包容量仍为c 的背包问题。若置x1 = 1,问题就变为关于背包容量为c-w1 的问题。现设r={c,c-w1} 为剩余的背包容量。在次决策之后,剩下的问题便是考虑背包容量为r 时的决策。不管x1 是0或是1,[x2 ,.,xn ] 必须是次决策之后的一个方案。也就是说在此问题中,决策序列由决策子序列组成。

设f (i,j) 表示剩余容量为j,剩余物品为i,i + 1,...,n 时的解的值,即:利用序列由子序列构成的结论,可得到f 的递归式为:

当j≥wi时:f(i,j)=max{f(i+1,j),f(i+1,j-wi)+pi}

当0≤j

这是一个递归的算法,其时间效率较低,为指数级。

考虑用动态规划的方法来解决:

阶段:在前i件物品中,选取若干件物品放入背包中;

状态:在前i件物品中,选取若干件物品放入所剩空间为c的背包中的所能获得的价值;

决策:第i件物品放或者不放;

由此可以写出动态转移方程:

用f[i,j]表示在前 i 件物品中选择若干件放在所剩空间为 j 的背包里所能获得的价值

f[i,j]=max{f[i-1,j-wi]+pi (j>=wi), f[i-1,j]}

这样,就可以自底向上地得出在前n件物品中取出若干件放进背包能获得的价值,也就是f[n,c]

算法框架如下:

for i:=0 to c do {i=0也就是没有物品时清零}

f[0,i]:=0;

for i:=1 to n do {枚举n件物品}

for j:=0 to c do {枚举所有的装入情况}

begin

f[i,j]:=f[i-1,j]; {先让本次装入结果等于上次结果}

if (j>=w[i]) and (f[i-1,j-w[i]]+p[i]>f[i,j]) {如果能装第i件物品}

then f[i,j]:=f[i-1,j-w[i]]+p[i]; {且装入后价值变大则装入}

end;

wrin(f[n,c]);

为了进一步说明算法的执行原理,下面给出一个实例:

【输入文件】

1var0

40 10 25 30

【输出结果】下面列出所有的f[i,j]

0 0 0 0 40 40 40 40 40 40

10 10 10 10 40 50 50 50 50 50

10 10 10 25 40 50 50 50 65 75

10 10 30 40 40 50 55 70 80 80

从以上的数据中我们可以清晰地看到每一次的枚举结果,每一行都表示一个阶段。

考虑下述背包问题的实例。有5件物品,背包容量为100。

45 1 4 3

贪心算法,在对问题求解时总是做出在当前看来是的选择(但结果未必是)

printf("请输入钱数:");

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,

这些子问题相互且与原问题性质相同.求出子问题的解,就可得到原问题的解.

典型的算法:汉诺塔,二分搜索

动态规划,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法

典型的算法:背包问题

回溯算法也叫试探法,它是一种系统地搜索问题的解的方法

典型算法:八皇后问题

按单位重量价值优先策略入包,就是当前看来(结果不一定)

这里采用的是贪心算法,

考虑0/1背包问题,入包的是1,2,3价值是430(50+200+180)

考虑部分入包的话,入包的是1,2,3,4(4入包40)价值是630(50+200+180+225/4540)

2,3,4价值的确是605,但那不是用贪心算法计算来的

所以是C

C语言 贪心算法求背包问题

while (r<=h)

分数太少了,个是动态规划,第二个是贪心,都挺简单的

还是给你写吧

#include

#include

int a[2000],b[200000],n,m,i,j;

int main()

{scanf("%d",&n);//钱种类

scanf("%d",&a[i]);//每个钱的面值

b[a[i]]=1;

for (i=1;i<=m;i++)

for (j=0;j

if (i-a[j]>0)

if (b[i]==0)

{if (b[i-a[j]]!=0)

b[i]=b[i-a[j]]+1;

}else

{if (b[i-a[j]]!=0&&b[i-a[j]]+1

b[i]=b[i-a[j]]+1;

}if (b[m]==0) printf("-1n");//找不开输出-1

else printf("%dn",b[m]);//可以找到交换策略,输出最小票数

return 0;

}第二题:

#include

struct good//表示物品的结构体

{double p;//价值

double w;//重量

double r;//价值与重量的比

}a[2000];

double s,value,m;

int i,n;

bool bigger(good a,good b)

{return a.r>b.r;

}int main()

{scanf("%d",&n);//物品个数

{scanf("%lf%lf",&a[i].w,&a[i].p);

a[i].r=a[i].p/a[i].w;

}sort(a,a+n,bigger);//调用sort排序函数,你大概不介意吧,按照价值与重量比排序贪心

scanf("%lf",&m);//读入包的容量m

s=0;//包内现存货品的重量

value=0;//包内现存货品总价值

for (i=0;i

{value+=a[i].p;

s+=a[i].w;

}printf("The total value in the bag is %.2lf.n",value);//输出结果

return 0;

}我可以帮助你,你先设置我后,我百度Hii教你。

分数太少了,个是动态规划,第二个是贪心,都挺简单的

还是给你写吧

#include

#include

int a[2000],b[200000],n,m,i,j;

int main()

{scanf("%d",&n);//钱种类

scanf("%d",&a[i]);//每个钱的面值

b[a[i]]=1;

for (i=1;i<=m;i++)

for (j=0;j

if (i-a[j]>0)

if (b[i]==0)

{if (b[i-a[j]]!=0)

b[i]=b[i-a[j]]+1;

}else

{if (b[i-a[j]]!=0&&b[i-a[j]]+1

b[i]=b[i-a[j]]+1;

}if (b[m]==0) printf("-1n");//找不开输出-1

else printf("%dn",b[m]);//可以找到交换策略,输出最小票数

return 0;

}第二题:

#include

struct good//表示物品的结构体

{double p;//价值

double w;//重量

double r;//价值与重量的比

}a[2000];

double s,value,m;

int i,n;

bool bigger(good a,good b)

{return a.r>b.r;

}int main()

{scanf("%d",&n);//物品个数

{scanf("%lf%lf",&a[i].w,&a[i].p);

a[i].r=a[i].p/a[i].w;

}sort(a,a+n,bigger);//调用sort排序函数,你大概不介意吧,按照价值与重量比排序贪心

scanf("%lf",&m);//读入包的容量m

s=0;//包内现存货品的重量

value=0;//包内现存货品总价值

for (i=0;i

{value+=a[i].p;

s+=a[i].w;

}printf("The total value in the bag is %.2lf.n",value);//输出结果

return 0;

}希望对你有帮助

是正确的 程序没有出错 是因为你的控制语句写错了 背包问题讲的是不能超过背包的总重量 三种物品的单位价值分别为1.2、1.5、1.25 挑选时先选1.5、1.25、1.2 重量分别为 10 8 才是2

建议你用一个数组对货物进行编号 这样分析时容易点 并且输出时清晰一点

你for (i=0;i

求所有背包问题源程序pascal+题目解析

for i:= 1 to n do

1.部分背包问题

var

一个旅行者有一个最多能用m公斤的背包,现在有n种物品,它们的总重量分别是W1,W2,...,Wn,它们的总价值分别为C1,C2,...,Cn.求旅行者能获得总价值。

2.0/1背包

一个旅行者有一个最多能用m公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn.若每种物品只有一件求旅行者能获得总价值。

<1>分析说明:

显然这个题可用深度优先方法对每件物品进行枚举(选或不选用0,1控制).

程序简单,但是当n的值很大的时候不能满足时间要求,时间复杂度为O(2n)。按递归的思想我们可以把问题分解为子问题,使用递归函数

设 f(i,x)表示前i件物品,总重量不超过x的价值

则 f(i,x)=max(f(i-1,x-W[i])+C[i],f(i-1,x))

f(n,m)即为解,边界条件为f(0,x)=0 ,f(i,0)=0;

动态规划方法(顺推法)程序如下:

程序如下:

program knapsack02;

const maxm=200;maxn=30;

var m,n,j,i:integer;

c,w:ar;

f:array[0..maxn,0..maxm] of integer;

function max(x,y:integer):integer;

begin

if x>y then max:=x else max:=y;

end;

begin

readln(m,n);

readln(w[i],c[i]);

for i:=1 to m do f(0,i):=0;

for i:=1 to n do f(i,0):=0;

for i:=1 to n do

for j:=1 to m do

begin

if j>=w[i] then f[i,j]:=max(f[i-1,j-w[i]]+c[i],f[i-1,j])

else f[i,j]:=f[i-1,j];

end;

wrin(f[n,m]);

end.

使用二维数组存储各子问题时方便,但当maxm较大时如maxn=2000时不能定义二维数组f,怎么办,其实可以用一维数组,但是上述中j:=1 to m 要改为j:=m downto 1,为什么?请大家自己解决。

3.完全背包问题

一个旅行者有一个最多能用m公斤的背包,现在有n种物品,每件的重量分别是W1,W2,...,Wn,

每件的价值分别为C1,C2,...,Cn.若的每种物品的件数足够多.

求旅行者能获得的总价值。

本问题的数学模型如下:

则 f(x)=max{f(x-w[i])+c[i]} 当x>=w[i] 1<=i<=n

程序如下:(顺推法)

program knapsack04;

const maxm=2000;maxn=30;

type ar=array[0..maxn] of integer;

var m,n,j,i,t:integer;

c,w:ar;

f:array[0..maxm] of integer;

begin

readln(m,n);

readln(w[i],c[i]);

f(0):=0;

for i:=1 to m do

for j:=1 to n do

begin

if i>=w[j] then t:=f[i-w[j]]+c[j];

if t>f[i] then f[i]:=t

end;

wrin(f[m]);

end.