动态规划模型2,01背包问题
2013-02-17 14:20 Dr.Ray 阅读(359) 评论(0) 收藏 举报01背包问题:
有n个物品,每个体积为v[1-n],问这些物品能否装满体积为b的背包,物品不能切分,形状因素忽略不计。求背包最小剩余空间。
阶段:以v数组的下标划分
状态:opt[]为0或1
状态转移方程:opt[j] = opt[j - v[i]]
思路:
opt[b+1]代表体积为0~b的背包能否被装满,0否1能;
于是就要知道所有物品体积组合之和。
我理所因当想到用循环,多层循环强行组合不可能,因为循环层数不确定。
可以用两层循环如//key!,先记一个物品v1体积的opt[v1]=1,接着只要体积v2于之前出现过的体积v1加上另一个物品的体积则opt[v2]=1。
注意第二层必须用倒推,否则 j-v[i]会等于v[i],导致j = n*v[i]时也可以被填满,但是i物体只有一个,于是错误。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int v,n;
FILE *fin;
fin = fopen("in.txt","r");
while(fscanf(fin, "%d%d", &v,&n) != EOF)
{
int opt[v+1], v[n];
memset(opt, 0, sizeof(opt));
opt[0] = 1;
for(int i=0; i<n; i++)
{
fscanf(fin, "%d", v[i]);
}
//key!寻找每个可能的体积和
for(int i=0; i<n; i++)
for(int j = v; j>=v[i]; j--)
{
if(opt[j - v[i]])
opt[j] = 1;
}
//找到最大的可行解
for(int i=v; i>=0; i--)
{
if(opt[i] == 1)
printf("%d\n", v-i);
}
return 0;
}