您的位置:首页 > 其它

背包问题与动态规划问题初学

2011-03-24 22:34 435 查看

01背包

状态转移方程:

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

本人初学,在网上找了N久的动态规划和01背包的资料,虽然有一些讲的很生动,我也在概念上理解了动态规划和01背包的原理,但是总觉得无法形象的表达整体的运算过程,于是画了个表格形象地记录一下这个过程。



上面箭头表示了每次的比较的两个数据,较大的存放在箭头的尾部,根据观察可以看出,每次比较的都是本次第N个数据与上次循环结果的第(N-此次物品重量)个数据,也就是没放入这个物品之前的最优解。

每一列代表每个不同容量的背包的情况 每行代表放入不同物品的情况。

粘个一维数组实现的代码

#include <iostream>

using namespace std;

int main(void){
int cases=0;
int maxVolume=0;
int nGoods=0;
int weight[1024];
int value[1024];
int record[1024];
cin>>cases;
while(cases--){

memset(record,0,sizeof(record));

cin>>nGoods>>maxVolume;
for(int i=0;i<nGoods;i++)
cin>>value[i]>>weight[i];

for(i=0;i<nGoods;i++)
for(int j=maxVolume;j>=weight[i];j--)
if(record[j]<record[j-weight[i]]+value[i])
record[j]=record[j-weight[i]]+value[i];

cout<<record[maxVolume]<<endl;
}

return 0;
}


#include <iostream>

using namespace std;

int main(void){
int cases=0;
int maxVolume=0;
int nGoods=0;
int weight[1024];
int value[1024];
int record[1024];
cin>>cases;
while(cases--){

memset(record,0,sizeof(record));

cin>>nGoods>>maxVolume;
for(int i=0;i<nGoods;i++)
cin>>value[i]>>weight[i];

for(i=0;i<nGoods;i++)
for(int j=maxVolume;j>=weight[i];j--)
if(record[j]<record[j-weight[i]]+value[i])
record[j]=record[j-weight[i]]+value[i];

cout<<record[maxVolume]<<endl;
}

return 0;
}


多重背包

状态转移方程:

f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k<=n[i]}

[b](0<=k<=v/w[i])[/b]

[b]待续...[/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: