今天看算法导论dp。
这样的一道题 叙述和01背包一样
有n个重量和价值分别为wi vi的物品。 从这些物品中挑选总重量不超过W的物品,求所有挑选方案中价值总和的最大值。
注意限制条件
1<=n<=100
1<=wi<=1e7
1<=vi<=100
1<=W<=1e9
如果还是按照之前的 用价值转移的话
会发现这个算法会T
因为那个的复杂度是 O(nW)
所以这次的
dp[i+1][j]
是前i个物品中价值为j时的最小重量值
不存在时就是一个重量就是INF 初始化的时候用的 之后会提到
我在这里用的2e9
其实只要比1e9大就行
还有就是初始化 dp[0][0]=0 dp[0][j]=INF
这并不是说 前0个物品挑选价值为j的 最小重量是INF 而是相当于用这个INF 代表这种情况不存在
可以想一想为什么 dp[ 0][ 0] 为什么不是INF
下面是我的代码 大家可以看一看 不懂的可以互相交流 觉得写得不好的也可以提一提意见哈~~
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=100,maxv=100;
int maxw,n;
int dp[maxn+5][maxn*maxv+5];
int w[maxn],v[maxn];
const int INF=2000000000;
void init()
{
for(int j=0;j<maxn*maxv;j++)
dp[0][j]=INF;
}
void solve()
{
for(int i=0;i<n;i++)
for(int j=0;j<=n*maxv;j++)
{
if(j<v[i])
dp[i+1][j]=dp[i][j];
else
dp[i+1][j]=min(dp[i][j],dp[i][j-v[i]]+w[i]);
}
int ans=0;
for(int i=0;i<=n*maxv;i++)
if(dp[n][i]<=maxw) ans=i;
printf("%d\n",ans);
}
int main()
{
scanf("%d%d",&n,&maxw);
init();
dp[0][0]=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&w[i],&v[i]);
}
solve();
return 0;
}