01背包问题
百度百科上的一个算法:#include"stdafx.h"#include<iostream>usingnamespacestd;#defineMAXSIZE1000in...
百度百科上的一个算法:
#include "stdafx.h"
#include <iostream>
using namespace std;
#define MAXSIZE 1000
int f[MAXSIZE + 1],c[MAXSIZE + 1],w[MAXSIZE + 1];
int _tmain(int argc,_TCHAR* argv[])
{
int N,V;
cin >> N >> V;
int i = 1;
for (; i <= N; ++i)
{
cin >> c[i] >> w[i];
}
for (i = 1; i <= N; ++i)
{
for (int v = V; v >= c[i]; --v) //c[i]可优化为bound,bound = max {V - sum c[i,...n],c[i]}
{
f[v] = (f[v] > f[v - c[i]] + w[i])?f[v] : f[v - c[i]] + w[i];
}
}
//当i=N时,可以跳出循环单独计算F[V]
cout << f[V] << '\n';
system("pause");
return 0;
}
为什么for (int v = V; v >= c[i]; --v) 这里V为什么逆序
百度百科上的原话看不懂啊 (我怎么这么笨啊。。。):
f[i][v]是由f[i-1][v]和f [i-1][v-c[i]]两个子问题递推而来,能否保证在推f[v]时(也即在第i次主循环中推f[v]时)能够得到f[v]和f[v -c[i]]的值呢?事实上,这要求在每次主循环中我们以v=V..0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值 展开
#include "stdafx.h"
#include <iostream>
using namespace std;
#define MAXSIZE 1000
int f[MAXSIZE + 1],c[MAXSIZE + 1],w[MAXSIZE + 1];
int _tmain(int argc,_TCHAR* argv[])
{
int N,V;
cin >> N >> V;
int i = 1;
for (; i <= N; ++i)
{
cin >> c[i] >> w[i];
}
for (i = 1; i <= N; ++i)
{
for (int v = V; v >= c[i]; --v) //c[i]可优化为bound,bound = max {V - sum c[i,...n],c[i]}
{
f[v] = (f[v] > f[v - c[i]] + w[i])?f[v] : f[v - c[i]] + w[i];
}
}
//当i=N时,可以跳出循环单独计算F[V]
cout << f[V] << '\n';
system("pause");
return 0;
}
为什么for (int v = V; v >= c[i]; --v) 这里V为什么逆序
百度百科上的原话看不懂啊 (我怎么这么笨啊。。。):
f[i][v]是由f[i-1][v]和f [i-1][v-c[i]]两个子问题递推而来,能否保证在推f[v]时(也即在第i次主循环中推f[v]时)能够得到f[v]和f[v -c[i]]的值呢?事实上,这要求在每次主循环中我们以v=V..0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值 展开
2个回答
展开全部
就是所谓01背包,一个物品只能被用一次,因此当状态简化为一维(即f[])时,f[v]是从f[v - c[i]]
转移而来,所以,为了保证只用一次就需要倒序枚举了。
二维状态的时候就没关系。
转移而来,所以,为了保证只用一次就需要倒序枚举了。
二维状态的时候就没关系。
更多追问追答
追问
为什么保证只用1次就是倒叙枚举啊 虽然顺序枚举明显会减成负数 好难想啊
我好像懂了一些了 但是这算法 要实打实想出来不好想啊 怎么想到这样写的啊
来自:求助得到的回答
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询